- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
刚刚开始学习Haskell并且我试图实现一个 max 函数来递归地查找列表的最大值
max' :: (Num b) => [a] -> b
max' [] = 0
max' (x:xs)
| x > max' xs = x
| otherwise = max' xs
但是在尝试编译时出现错误
Couldn't match expected type ‘b’ with actual type ‘a’ ‘a’ is a rigid type variable bound by the type signature for: max' :: forall b a. (Num b, Num a) => [a] -> b at implementingFunctions.hs:5:1-34 ‘b’ is a rigid type variable bound by the type signature for: max' :: forall b a. (Num b, Num a) => [a] -> b at implementingFunctions.hs:5:1-34
任何人都可以帮助我理解出了什么问题吗?
最佳答案
max'
将 [a]
作为输入(基于签名) : a
的列表s。但你返回一个b
。这意味着您已经编写了 - 无论列表中元素的类型如何 - 我们都可以选择任何类型 b
作为我们想要的输出,只要是 Num b
。但这没有意义。如果我们输入一个字符串列表,我们当然可以计算“最大字符串”(按字典顺序),但我们不能将其返回为 Num
.
另一个问题是您使用 (>) :: Ord a => a -> a -> Bool
功能(作为 guard )。但您没有在函数签名中指定输入元素的类型必须是 Ord
的实例。类型类。所以你不能比较元素。
最小的修复是将输入类型限制为 b
还有:
max' :: <b>(Ord b, </b>Num b<b>)</b> => [<b>b</b>] -> b
max' [] = 0
max' (x:xs)
| x > max' xs = x
| otherwise = max' xs
话虽如此,返回 0
并没有多大意义。如果我们提供一个空列表。这会导致一个奇怪的事实:max []
实际上大于max [-1]
:通常我们期望超集的最大值大于或等于集合的最大值。
所以max'
函数可能最好被视为非全函数:并非每个输入都会产生输出的函数。在这种情况下,空列表不会。
我们可以将其重写为错误:
max' :: Ord b => [b] -> b
max' [] = <b>error "Empty list"</b>
<b>max' [x] = x</b>
max' (x:xs@(_:_))
| x > max' xs = x
| otherwise = max' xs
现在有三种模式:(1) 空列表,(2) 单例列表,(3) 至少有两个元素的列表。
然而,编写错误并不总是处理非完整函数的好方法,因为人们无法在类型签名中看到函数是非完整的。另一种方法是使用 Maybe b
作为返回类型。这将是 Nothing
如果没有最大值,或者 Just x
如果有的话:
max' :: Ord b => [b] -> <b>Maybe </b>b
max' [] = <b>Nothing</b>
max' [x] = <b>Just x</b>
max' (x:xs@(_:_))
| <b>y <- max' xs = max x y</b>
| otherwise = Nothing
或更短:
max' :: Ord b => [b] -> Maybe b
max' [] = <b>Nothing</b>
max' [x] = <b>Just x</b>
max' (x:xs@(_:_)) = <b>fmap (max x) (max' xs)</b>
例如:
Prelude> max' []
Nothing
Prelude> max' [1,4,2,5]
Just 5
Prelude> max' [-3]
Just (-3)
关于Haskell - 无法将预期类型 ‘b’ 与实际类型 ‘a’ 匹配,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47210822/
我是一名优秀的程序员,十分优秀!