我很确定我的问题源于我是Haskell的新手并且完全不了解类型系统的事实.
我将使用Haskell的wiki中使用的类型主题示例
定义了以下类型
data Suit = Club | Diamond | Heart | Spade
现在第一个问题是,我想Show
为每个"子类型"(Club,Diamond,Heart,Spade)实施,但这似乎不起作用,因为它是一个DataKinds
.所以我把它分成了自己的类型.(属性没有多大意义,但我添加它们更接近实际代码)
data ClubType = ClubType { clubName :: String, icon :: String } instance Show ClubType where show (ClubType cn i) = "name: " ++ cn ++ ", icon: " ++ i
在Suit类型中使用它们
data Suit = Club ClubType | Diamond DiamondType | Heart HeartType | Spade SpadeType
现在我想用不同的西装和"子类型"(俱乐部,钻石,心脏,锹)module
.我只是出口了Suit (..)
.
用法
import Module1 (Suit(..)) getSuit :: String -> Suit getSuit "Club" = getClub getSuit "Heart" = getHeart ... getClub :: () -> Club
现在再次Club
,Heart
,Diamond
而Spade
不能使用,因为它们DataKinds
.我如何使用"子类型"?我需要导出所有类型吗?如果我这样做,它是否符合返回类型getSuit
?
(对不起,如果这个例子没有多大意义,但我希望你能按照我想要的结果)
谢谢
是的,听起来你并不真正了解类型系统.我会尽力澄清我认为你出错的地方.在你的例子中
data Suit = Club | Diamond | Heart | Spade
只有一种类型,就是这样Suit
. Club
,Diamond
等等根本不是类型,如果你把它们称为"子类型",你会感到困惑.它们的正确名称是构造函数,它们本质上是类型的值Suit
Club :: Suit Diamond :: Suit ...
所以你不能真正Show
为"每一个"实现一个Show
实例,你只能Suit
通过构造函数上的模式匹配以通常的方式实现整个类型的实例:
instance Show Suit where show Club = "Clubs" show Diamond = "Diamonds" show Heart = "Heart" show Spade = "Spade"
这定义了show
类型上的单个函数Suit -> String
,同样没有"子类型"发生任何事情.我想知道这是否就是你想要的.
既然你提到了datakinds,那么使用类型级别的构造函数仍然不会使它们成为类型 - 它们仍然是类型的值Suit
.在类型级别使用它们的一个示例是通过以下方式索引GADT:
data Card :: Suit -> * where QueenOfSpades :: Card Spade OtherCard :: Int -> Card s -- we'd want to encode the suit s at the data -- level too using a singleton, out of scope -- for this post
但这是相当先进的东西,可能不是你想要的东西.
我希望这能澄清一些事情.