首先,这是我的代码的最小示例:

{-# LANGUAGE GADTs #-}

-- package "url"
import Network.URL (exportURL, URL(..), URLType(..))

data MyURL a where
    GalleryURL :: URL -> MyURL URL
    PictureURL :: URL -> MyURL URL

url = URL { url_type = PathRelative,
            url_path = "www.google.com",
            url_params = []}

galleryURL = GalleryURL url

myExportURL :: MyURL a -> String
myExportURL (GalleryURL a) = exportURL a
myExportURL (PictureURL a) = exportURL a

main = print $ myExportURL galleryURL


我使用GADT来避免混合使用各种URL。 myExportURL函数对于所有类型的URL都是相同的。有没有办法使用这样的东西:

myExportURL (_ a) = exportURL a


而不是针对GADT的每个子类型(正确的术语是什么)重复它?

也欢迎对代码或我要解决的问题有任何其他评论。

最佳答案

正确的术语是“对于每个构造函数”。

您的GADT看起来可疑,因为所有构造函数都构造相同的MyURL URL类型。如果仅此而已,那么您就不需要GADT了,可以使用普通的ADT:

data MyURL = GalleryURL URL | PictureURL URL


要使myExportUrl较短,有不同的选择。一种是重构类型:

data URLKind = GalleryURL | PictureURL
data MyURL = MyURL { myUrlKind :: URLKind, myExportURL :: URL }


这样,您仍然可以使用“简短”形式的结构,例如MyURL PictureURL foo。您也可以使用Haskell为您生成的myExportURL函数。

GADT仅在高级情况下才是必需的,因此,如果您的示例不能充分说明为什么需要GADT,请立即联系我们。

10-06 03:24