gpt4 book ai didi

haskell - 具有函数组合的类型推断列表

转载 作者:行者123 更新时间:2023-12-02 14:20:42 25 4
gpt4 key购买 nike

我正在尝试使用折叠来计算 Haskell 中整数和的平方。然而,我从 GHCi 收到了一个神秘的错误。这是我的一句台词:

((^2) . foldl) (+) 0 [1..100]

我从 GHCi 得到的是:

Prelude> ((^2) . foldl) (+) 0 [1..100]

<interactive>:19:3:
No instance for (Num (b0 -> [b0] -> b0))
arising from a use of `^'
Possible fix:
add an instance declaration for (Num (b0 -> [b0] -> b0))
In the first argument of `(.)', namely `(^ 2)'
In the expression: (^ 2) . foldl
In the expression: ((^ 2) . foldl) (+) 0 [1 .. 100]

我认为问题出在我基于此类型声明最后传入的列表中。

Prelude> :t ((^2) . foldl) (+) 0 [1..100]
((^2) . foldl) (+) 0 [1..100]
:: (Enum b, Num b, Num (b -> [b] -> b)) => b

任何人都可以让我深入了解为什么这种类型需要 Enum 以及任何显式转换列表以便我可以调试此函数的方法吗?提前致谢。

最佳答案

是的,这仍然是 GHC 产生的最 absurd 和最无用的错误消息之一。

首先,忽略消息,考虑foldl(.)的类型:

foldl :: (a -> b -> a) -> a -> [b] -> a
(.) :: (b -> c) -> (a -> b) -> a -> c

请注意,(.) 仅使用第一个参数进行组合。由于柯里化(Currying),具有“多个”参数的函数实际上是一个返回另一个函数的参数的函数。因此,在表达式 ((^2) .foldl) 中,foldl 的“返回类型”为 a -> [b] -> a ,这就是它尝试与 (^ 2) 组合的内容。

因为错误消息很愚蠢,所以它提示 a -> [b] -> a 没有 Num 实例,以便与 组合它>(^2)::Num a => a -> a 并建议您添加一个。

你想要的是这样的:((^2) .foldl (+) 0)。也就是说,使用(懒惰的)foldl 在这里可能是一个坏主意。最好使用严格的 foldl' ,或者更好的是,内置的 sum 函数: (^2) 。总和

此外,类型中提到的 Enum 约束是不相关的,而且实际上是正确的 - Enum 类型类提供了用于解释范围表示法的函数。所以 (Enum b, Num b) => ... 意味着 b 是一个可以枚举的数字类型,这正是表达式 所需要的>[1 .. 100].

关于haskell - 具有函数组合的类型推断列表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16128251/

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