haskell的新手,当我尝试对非空列表进行模式匹配时,我一直遇到这个神秘错误
代码:
type Bits = [Bool]
nor :: Bits -> Bits -> Bits
nor [] [_:__] = error "mismatched length"
nor [_:__] [] = error "mismatched length"
nor [] [] = []
nor (x:xs) (y:ys) = (norBit x y):nor xs ys
where norBit x y = if x == True || y == True then False else True
main = do
print (nor [True] [False])
错误:
gates.hs:4:9:
Couldn't match expected type ‘Bool’ with actual type ‘[t0]’
In the pattern: _ : __
In the pattern: [_ : __]
In an equation for ‘nor’: nor [] [_ : __] = []
答案 0 :(得分:5)
Haskell中的列表构造函数为[]
和(x:xs)
,请注意,第二个构造函数使用 round 括号。
如果您编写[_:__]
,那么这也是有效的语法:由于Haskell认为您编写了模式[(x:xs)]
,因此是 singleton 列表,其中 first 元素与(x:xs)
模式匹配。但这应意味着该类型是[[a]]
而不是[a]
,并且由于Bool
不是列表类型的类型别名,因此问题无法解决。
您可以在此处写出圆括号
来解决这种情况:nor :: Bits -> Bits -> Bits
nor [] (_:_) = error "mismatched length"
nor (_:_) [] = error "mismatched length"
nor [] [] = []
nor (x:xs) (y:ys) = (norBit x y):nor xs ys
where norBit x y = if x == True || y == True then False else True
或者我们可以将函数重写为:
nor :: Bits -> Bits -> Bits
nor (x:xs) (y:ys) = not (x || y) : nor xs ys
nor [] [] = []
nor _ _ = error "mismatched length"
请注意,由于懒惰,例如,如果您对结果进行take k
,而k
小于两个列表的长度,则不会引发错误。