首先,如果您尝试加载给定的定义,则会收到错误消息,
....
No instance for (Num a) arising from the literal `0'
Possible fix:
add (Num a) to the context of
the type signature for mymaximum :: List a -> a
....
所以这表明您需要将类型签名更改为
mymaximum :: (Num a) => List a -> a
现在错误信息是
....
Could not deduce (Ord a) arising from a use of `>'
from the context (Num a)
bound by the type signature for mymaximum :: Num a => List a -> a
at <interactive>:59:14-35
Possible fix:
add (Ord a) to the context of
the type signature for mymaximum :: Num a => List a -> a
....
同样,我们将类型签名更改为
mymaximum :: (Num a, Ord a) => List a -> a
现在 GHCi 响应:
mymaximum :: (Num a, Ord a) => List a -> a
意思是,它接受了带有类型签名的定义。
现在这个函数将适用于所有实现Num 和Ord 类型类的类型。
Int 是一个,Float 是另一个。 Char 不是。但是如果你import Data.Char,你可以使用函数
chr :: Int -> Char
ord :: Char -> Int
要解决这个问题,通过将ord 映射到您的List Char 值(您还必须为此定义自己的map 函数......也许),找到您的最大值,然后使用@ 向后工作987654336@恢复字符。
更新: 正如您所注意到的,将特殊大小写 0 作为空列表的最大值不是正确的做法。将一个元素列表作为您的基本案例是一个很好的解决方案。现在可以删除Num a 约束,并且该函数也可以用于List Char 参数或任何Ord a => List a 类型的值,从而产生Ord a => a 类型的值。
但有一点需要注意:您仍然需要处理空列表的情况,可能通过调用 error 并带有特定的错误消息,例如
mymaximum ListEnd = error " mymaximum: empty list is not allowed! "