[英]Get sum of int or integer in Haskell
此函數應適用於Int列表和Integer列表:
myFunc :: [Integer] -> [Char]
myFunc x = if (sum x `mod` 2 ==1) then "odd" else "even"
但它只適用於整數列表。
類型類提供了一種關於類型的通用方法(它們實際上是類型組)。 您可以使用類型類約束而不是顯式類型Integer
,如下所示:
myFunc :: Integral a => [a] -> String
myFunc x = if (even (sum x)) then "even" else "odd"
這將做的是指定它是從[a]
到String
的函數,其中a
是一個類型變量,並且只要它是Integral
類型類的成員就被約束為任何類型。 另一種說法是任何類型,只要它有一個Integral
類型類的實例 。 這意味着它具有為該特定類型指定的類型類的方法。
Integral
類型類用於值為Integral
類型(即積分)。
令人高興的是Int
和Integer
都為Integral
提供了一個實例,所以我們可以使用它。
Int和Integers是不同的類型。 它們都是Integral類型類的實例,但它的“mod”是其函數之一。
為了讓你的函數適用於特定類型以外的東西,你想要做的就是說函數,而不是[Integer] - > [Char]或[Int] - > [Char],類型應該比其中一個更少限制; 它應該是[a] - > [Char]。 但是如果你聲明了那個實例,它就不會編譯,因為有兩件事:
1)總和要求你的x是一個數字列表。 那是,
sum :: Num a => [a] -> a;
Num是另一個類型類,它需要任何類型的Num實例來包含(+)的定義 ,以及其他內容; 這允許sum使用加法來添加所有數字。
2)mod要求你的x之和具有一個Integral實例的類型。 所以
mod (sum x) :: Integral a => a -> a
從技術上講,它還要求類型是Num的一個實例,因為sum x必須是,但Integral的定義要求Integral的任何實例也是Real的一個實例,而后者又需要它的類型為Num - 基本上你得到數量為實例Num的類型的免費要求。
所以,最后,你需要讓第一個類型成為'變量'(並不真正知道它的術語)類型,但需要是一個類型為Integral的類型:
myFunc :: Integral a => [a] -> [Char]
myFunc x = if (sum x `mod` 2 ==1) then "odd" else "even"
此外,如果您不包含類型聲明(即myFunc :: Integral a => [a] - > [Char]),編譯器將通過假設所有這些來自動填充空白。 類型聲明用於闡明函數的類型,限制函數的適用性,或者向編譯器說明變量在由於某種原因無法推斷類型時的類型。 但是,如果您不願意,通常不必聲明類型。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.