Haskell中

时间:2017-09-24 16:54:39

标签: haskell

我对Haskell很新,我试图创建一个能找到列表均值的基本函数。我几乎已经解决了,除了我必须做的最后一点分裂。

randInts = take 5 $ randoms (mkStdGen 11) :: [Int]

listSum :: (Num a) => [a] -> a
listSum [] = 0
listSum (x:xs) = x + listSum xs

listLength :: (Num a) => [a] -> a
listLength [] = 0
listLength (x:xs) = 1 + listLength xs

listMean :: (Num a) => [a] -> a
listMean [] = 0
listMean x = (listSum x) / (listLength x)

这就是我的开始,其中listSum和listLength基本上分别具有与列表上的sum和length运算符相同的功能,listMean将这两个运算符分开并将它们分开。然而,当我运行这个时,我得到一个错误,说"无法从上下文中使用'/'推断出(小数a):Num a"

首先,我只是认为我使用了错误的类型并将listMean切换为listMean ::(Fractional a)=&gt; [a] - &gt;一个。这允许我编译,但是当我试图通过给它randInts来运行它时,而是我得到了错误消息&#34;没有使用'listMean'产生的(Fractional Int)实例。&#34; < / p>

我不确定我在这里缺少什么。我可以请一些建议吗?

2 个答案:

答案 0 :(得分:2)

猜测:您正在使用listMean randInts在ghci中对此进行测试。这是一个问题,因为Int不支持通过(/)进行划分,而是支持通过div进行整数除法(以避免某些类型的错误出现在将两者混为一谈的语言中)。

您有两个明显的选择,即将您的Int转换为支持除法的内容(例如Double)或首先生成随机Double

listMean (map fromIntegral is) :: Double
listMean . take 5 . randoms $ mkStdGen 11 :: Double

顺便说一句,如果我的猜测是正确的:将来,你应该真的包含所有你做过的事情的细节,我们在家里玩的非常详细的细节可以跟着他们并看到完全相同的错误; 你应该包含错误的全部内容,特别是因为在这种情况下,它会提到导致它的代码片段并且会立即进行诊断。

答案 1 :(得分:1)

问题在于:

(Num a) => [a] -> a

应用[Int]时,listSumlistLength都会返回Int,但不支持/。您需要在除法之前转换返回值:

listMean :: (Num a, Integral a) => [a] -> Double
listMean [] = 0
listMean x = (fromIntegral $ listSum x) / (fromIntegral $ listLength x)