我试图找到具有最小元素总和的列表:
shortest :: (Num a) => [[a]] -> [a]
shortest [] = []
shortest (x:xs) = if sum x < sum (shortest xs) then x else shortest xs
Run Code Online (Sandbox Code Playgroud)
这给了我以下错误:
Run Code Online (Sandbox Code Playgroud)Could not deduce (Ord a) arising from a use of `<' from the context (Eq a) bound by the type signature for shortest :: Eq a => [[a]] -> [a] at code.hs:(8,1)-(9,71) Possible fix: add (Ord a) to the context of the type signature for shortest :: Eq a => [[a]] -> [a] In the expression: sum x < sum (shortest xs) In the expression: if sum x < sum (shortest xs) then x else shortest xs In an equation for `shortest': shortest (x : xs) = if sum x < sum (shortest xs) then x else shortest xs
为什么没有功能类型检查?
Has*_*ant 16
此代码涉及两个类型类:Num
和Ord
.请注意,类型可以是成员Num
而不是Ord
,反之亦然.
类型sum
是Num a => [a] -> a
输入元素shortest
需要成为的成员Num
.您还在代码中执行以下操作:
sum x < sum (shortest xs)
Run Code Online (Sandbox Code Playgroud)
这意味着您<
在a
s 上使用运算符,但在您的类型签名中,您并不要求a
s是其实例,Ord
它定义<
:
class Eq a => Ord a where
compare :: a -> a -> Ordering
(<) :: a -> a -> Bool
...
Run Code Online (Sandbox Code Playgroud)
因此,您需要将该要求添加到您的类型签名:
shortest :: (Ord a, Num a) => [[a]] -> [a]
Run Code Online (Sandbox Code Playgroud)
或者你可以省略类型签名.
Num
不包括Ord
,所以你在类型签名中缺少Ord
约束a
.它应该是
shortest :: (Num a, Ord a) => [[a]] -> [a]
Run Code Online (Sandbox Code Playgroud)
您可以删除类型签名,GHC将为您推断.