簡體   English   中英

為什么haskell中的這個平均功能不起作用?

[英]Why doesn't this average function in haskell work?

我想在Haskell中創建一個簡單的平均(平均)函數,所以我在ghci中嘗試了以下內容:

ghci> let avg xs = (sum xs) / (length xs)

它會引發以下錯誤:

No instance for (Fractional Int)
  arising from a use of `/'
Possible fix: add an instance declaration for (Fractional Int)
In the expression: (sum xs) / (length xs)
In an equation for `avg': avg xs = (sum xs) / (length xs)

所以,我決定通過嘗試以下方法將其分解:

ghci> let a = (sum [1,2])
ghci> let b = (length [1,2])

這一切都很好。

那么我嘗試了以下內容

ghci> a/b

我收到以下錯誤:

Couldn't match expected type `Integer' with actual type `Int'
In the second argument of `(/)', namely `b'
In the expression: a / b
In an equation for `it': it = a / b

那么,在Haskell中IntegerInt不同? - 如果是這樣,我怎樣才能使原始功能起作用?

問題是

length :: [a] -> Int

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

所以,當你說whatever / length xs ,它不會輸入,因為Int不是分數數字類型! 這就是“No instance for ...”錯誤試圖告訴你的。 這個定義可行:

GHCi> let avg xs = sum xs / fromIntegral (length xs)

這里,我們使用fromIntegral :: (Integral a, Num b) => a -> b將我們從length得到的Int轉換為小數。 請注意,由此產生的函數僅適用於小數的列表(但例如avg [1,2,3]仍然可以正常工作)。

為了解釋你在“分片”中所做的錯誤,這是因為在let a = sum [1,2] ,列表的元素是整數,所以它們的和是一個整數,但是在let b = length [1,2] ,根據我在上面顯示的length類型,得到的長度是一個Int。 因此,當你執行a/b ,這會失敗,直到它意識到Int和Integer不是Fractional的實例 - 因為(/)接受兩個相同類型的參數,它不可能工作。

是的,Integer和Int是不同的 - Int是一個固定精度的整數類型,通常是數字的大小,就像C中的long一樣,而Integer是一個任意精度的bignum,能夠存儲任何整數; 或者至少,任何適合你的RAM的整數:)

另一種可能的方法是使用Data.List.genericLengthavg xs定義為sum xs / genericLength xs ,它可以使用任何數字類型,而不僅僅是Ints:

genericLength :: (Num b) => [a] -> b

為此,您必須在GHCi中import Data.List 另一種可能的方法(但一個導致完全不同的功能)將是使用整數除法: let avg xs = sum xs `div` length xs (注意: a `div` b只是div ab ;這個句法糖用於每個功能)。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM