gpt4 book ai didi

Haskell 除数

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

我遇到了一个问题,想要了解更多信息以及如何避免。我有这个代码

len :: (Num r ) => [a] -> r
len [] = 0
len xs = 1 + len ( tail xs )

avg :: (Num t) => [t] -> Double
avg xs = ( sum xs ) / ( len xs )

这会导致以下错误

len.hs:6:9:    Couldn't match expected type `Double' against inferred type `t'      `t' is a rigid type variable bound by          the type signature for `avg' at len.hs:5:12    In the expression: (sum xs) / (len xs)    In the definition of `avg': avg xs = (sum xs) / (len xs)

Now, I know this error (thanks to irc.freenode.net#haskell) is a result of the division function

(/) :: (Fractional a) => a -> a -> a

但是,我不知道该怎么办。我的 avg 函数签名应该与除法运算符的怪癖无关(需要 Fractional 类型类)。因此,我认为克服这个问题的正确方法是转换为实现分数类型的类型,但我不知道如何实现,或者即使这是正确的?有什么想法吗?

最佳答案

My avg function signature should have nothing to do with the division operator's quirks

这是为什么呢?如果您想计算一堆整数的平均值,则必须在某个时刻进行除法,因此您必须将它们从整数转换为您选择的支持除法的类型。仔细观察 Num 类(ghci 中的 :i Num)揭示了 avg 类型的一个问题:Num 没有足够的方法——基本上足以进行加法、乘法和减法。无法保证我给 avg 的数字可以转换为 Double

如果您输入一个无类型函数来计算平均值,Haskell 会以最通用的类​​型进行响应:

Prelude List> :type \x -> sum x / genericLength x
\x -> sum x / genericLength x :: (Fractional a) => [a] -> a

这就是 avg 的正确类型。

您可能会注意到 avg [1,2,3::Integer] 给出了类型错误。您可以通过首先将参数传递给 toRationalfromIntegral 来解决这个问题,它们使用 RealIntegral 实例分别为整数

<小时/>

关于表达式 sum [1,2,3]/len [1,2,3]:确实,像 1 这样的文字数字的类型为Num a => a,无论结果是什么类型都会调用 fromInteger,但是像 1/2 这样的表达式有更具体的Fractional a => a 的类型,如果您询问该表达式的类型而不是将其打印出来,您就可以看到它。

ghci 中的 :set -Wall 可能会有所帮助,每当为您选择默认类型时,它都会打开大量警告,提示最通用的类​​型可能不再是正确。

关于Haskell 除数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1816993/

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