为什么向此 Haskell 函数提供空列表会导致编译器错误?
Why does supplying an empty list to this Haskell function give compiler error?
此代码来自《为您学习 Haskell 好书!]:
maximum' :: (Ord a) => [a] -> a
maximum' [] = error "maximum of empty list"
maximum' [x] = x
maximum' (x:xs)
| x > maxTail = x
| otherwise = maxTail
where maxTail = maximum' xs
它在非空列表上工作正常,但提供一个空列表:
main = print $ maximum' []
给出此编译器错误:
Ambiguous type variable ‘a0’ arising from a use of ‘maximum'’
prevents the constraint ‘(Ord a0)’ from being solved.
这是为什么?当提供空列表时,代码不应该实际捕获它吗?我不明白错误信息。
Ambiguous type variable ‘a0’ arising from a use of ‘maximum'’ prevents the constraint ‘(Ord a0)’ from being solved.
这意味着当你调用maximum' []
时,[]
的类型不明确:可能是[Int]
或[()]
或其他。
在这种特殊情况下,结果恰好是相同的。编译器无法在这里证明这一点,通常情况并非如此。考虑这个函数:
readAndPrepend :: (Read a, Show a) => String -> [a] -> String
readAndPrepend s xs = show (read s : xs)
如果您调用 readAndPrepend "42" []
,则结果不明确:
ghci> readAndPrepend "42" ([] :: [Int])
"[42]"
ghci> readAndPrepend "42" ([] :: [Double])
"[42.0]"
ghci> readAndPrepend "42" ([] :: [()])
"[*** Exception: Prelude.read: no parse
ghci>
换句话说,a
类型变量是“未解”的,就像数学方程式中的自由x
。
您需要做的是选择您希望列表成为的类型并明确指定它:
main = print $ maximum' ([] :: [()])
此代码来自《为您学习 Haskell 好书!]:
maximum' :: (Ord a) => [a] -> a
maximum' [] = error "maximum of empty list"
maximum' [x] = x
maximum' (x:xs)
| x > maxTail = x
| otherwise = maxTail
where maxTail = maximum' xs
它在非空列表上工作正常,但提供一个空列表:
main = print $ maximum' []
给出此编译器错误:
Ambiguous type variable ‘a0’ arising from a use of ‘maximum'’ prevents the constraint ‘(Ord a0)’ from being solved.
这是为什么?当提供空列表时,代码不应该实际捕获它吗?我不明白错误信息。
Ambiguous type variable ‘a0’ arising from a use of ‘maximum'’ prevents the constraint ‘(Ord a0)’ from being solved.
这意味着当你调用maximum' []
时,[]
的类型不明确:可能是[Int]
或[()]
或其他。
在这种特殊情况下,结果恰好是相同的。编译器无法在这里证明这一点,通常情况并非如此。考虑这个函数:
readAndPrepend :: (Read a, Show a) => String -> [a] -> String
readAndPrepend s xs = show (read s : xs)
如果您调用 readAndPrepend "42" []
,则结果不明确:
ghci> readAndPrepend "42" ([] :: [Int])
"[42]"
ghci> readAndPrepend "42" ([] :: [Double])
"[42.0]"
ghci> readAndPrepend "42" ([] :: [()])
"[*** Exception: Prelude.read: no parse
ghci>
换句话说,a
类型变量是“未解”的,就像数学方程式中的自由x
。
您需要做的是选择您希望列表成为的类型并明确指定它:
main = print $ maximum' ([] :: [()])