Haskell 无法将预期类型 'Bool' 与类型 [t0] 匹配

Haskell cannot match expected type 'Bool' to type [t0]

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中的list构造函数是[](x:xs),注意第二个构造函数使用round括号

如果你写 [_:__],那么这也是有效的语法:因为 Haskell 认为你写了一个模式 [(x:xs)],所以 singleton 列表,其中 first 元素匹配 (x:xs) 模式。但这应该意味着类型是 [[a]],而不是 [a],并且由于 Bool 而不是 列表的类型别名类型,问题无法解决。

你可以通过写圆括号:

来解决这个问题
nor :: Bits -> Bits -> Bits
nor [] <b>(_:_)</b> = error "mismatched length"
nor <b>(_:_)</b> [] = 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 小于 both 列表的长度,它不会引发错误。