首先,这是我的代码的最小示例:
{-# 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,请立即联系我们。