gpt4 book ai didi

Haskell - 无法将预期类型 ‘b’ 与实际类型 ‘a’ 匹配

转载 作者:行者123 更新时间:2023-12-02 17:37:52 25 4
gpt4 key购买 nike

刚刚开始学习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/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com