如何在Haskell中使用数据类型返回多个类型的函数?

时间:2016-10-30 19:41:43

标签: haskell

所以在我的代码中,我将数据类型Token声明为:

data Token = Char | Int
deriving (Show,Eq,Ord)

和声明为

的函数readIfNumber
readIfNumber :: Char -> Token 
readIfNumber a 
    | isDigit a = Token (digitToInt a)
    | otherwise = Token a

但是当我尝试编译时,控制台返回错误"期望类型令牌,但得到了Char"或者"期待令牌,但得到了Int"根据我的Token声明,当Int被视为令牌时。我在这做错了什么?

1 个答案:

答案 0 :(得分:7)

在变体类型中,您始终需要明确指出您采用的选项。即你需要使用构造函数明确地“标记”两个分支。像,

data Token = CharToken Char | IntToken Int

当实际从char或int构建一个令牌时,你将它包装在合适的构造函数中:

readIfNumber a 
 | isDigit a = IntToken $ digitToInt a
 | otherwise = CharToken a

需要这个原因吗?好吧,Haskell有完整的type erasure,即在编译时完全跟踪,决定和优化类型。在运行时,您不知道包含的类型是char还是int。有时这没关系,即你有多态行动。例如,length实际上并不关心列表中包含的元素的类型,因为它只处理列表的结构

但是,在这种情况下,收到Token 的人需要知道它是char还是int,才能进一步正确处理它。因此需要标记包含哪种类型。