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 [] [_ : __] = []
Haskell中的列表构造函数是[]
和(x:xs)
,请注意,第二个构造函数使用圆括号。
如果你写[_:__]
,那么这也是有效的语法:因为Haskell认为你写了一个模式[(x:xs)]
,所以是一个单例列表,其中第一个元素与(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
小于两个列表的长度,它不会引发错误。