我正在尝试解决Haskell Book中第11章“代数数据类型”中的章节练习之一。但是我遇到了一个类型错误,无法理解为什么一个非常相似的函数有效,而另一个则没有。
这就是我的开始:
type Digit = Char
type Presses = Int
data DaPhone =
DaPhone [(Char, Digit, Presses)]
deriving Show
myPhone :: DaPhone
myPhone =
DaPhone [('a', '2', 1), ('b', '2', 2), ('c', '2', 3)]
reverseTaps :: DaPhone -> Char -> [(Digit, Presses)]
reverseTaps aPhone aChar = foldr f [] aPhone
where f (c, d, p)
| c == aChar = ((d, p):)
f _ = id
并收到以下错误:
daPhone.hs:29:39: Couldn't match expected type ‘t0 (Char, Digit, Presses)’ …
with actual type ‘DaPhone’
In the third argument of ‘foldr’, namely ‘aPhone’
In the expression: foldr f [] aPhone
Compilation failed.
但是如果我尝试使用几乎相同类型的几乎相同的函数,例如:
myList :: [(Char, Char, Int)]
myList = [('a', '2', 1), ('b', '2', 2), ('c', '2', 3)]
myFunction :: [(Char, Char, Int)] -> Char -> [(Char, Int)]
myFunction aList aChar = foldr f [] aList
where f (c, d, p)
| c == aChar = ((d,p):)
f _ = id
它按预期编译和工作:
λ> myFunction myList 'a'
[('2',1)]
λ> myFunction myList 'b'
[('2',2)]
λ> myFunction myList 'c'
[('2',3)]
那么,为什么我在reverseTaps
中出现类型错误,这与myFunction
非常相似? (我想这是关于DaPhone的定义,意思是我可能需要在foldr
等中进行更多的模式修补,但我找不到具体的方法。)
答案 0 :(得分:3)
在我看来,你只需要
myFunction (DaPhone aList) aChar = ...
将DaPhone
解包为实际的列表。