不能真正遵循下面的類型推論,案例1工作但案例2失敗,爲什麼?如何關注Haskell中的類型推斷?
ghci> :t sqrt . maximum . map (+1) -- case 1
(Floating c, Ord c) => [c] -> c
ghci> :t sqrt . maximum . map length -- case 2
Could not deduce (Floating Int) arising from a use of ‘sqrt’
from the context (Foldable t)
bound by the inferred type of it :: Foldable t => [t a] -> Int
@EDIT
在OOP,Num
是後容易下界其所有subtypes
例如Int
和Float
。因此,如果Num
是合格類型,則Int
將被推斷爲可接受,但反之亦然。
此外,在類似C的語言中,內置的數字轉換可以自動滿足從較低精度到較高精度的情況。從Int
到Float
。相比之下,在Haskell上HM type system,Num
對於其所有instances
例如是class
。例如Int
和subclasses
,例如Floating
。合格類型可以在祖先和後代之間進行雙向推理,例如,從Num
到Int
,Floating
或反之亦然,但不在Int
和Floating
之間。
爲了補救殼體2,Int
應首先被適配成通過Num
或fromIntegral
施加Data.List.genericLength
產生Num
- 的推論限定類型爲Floating
該sqrt
需要。
讓我們將上述各點遵循以下類型推論,
ghci> :t (+)
Num a => a -> a -> a
ghci> :t 1.1
Fractional a => a
ghci> :i Fractional
class Num a => Fractional a
instance Fractional Float
instance Fractional Double
ghci> :t 1
Num a => a
ghci> :t length [1]
Int
ghci> :i Int
instance Num Int
instance Real Int
instance Integral Int
ghci> :t 1.1 + 1 -- case 1
Fractional a => a
ghci> :t 1.1 + length [1] -- case 2
No instance for (Fractional Int) arising from the literal ‘1.1’
'length'函數返回一個'Int',但'sqrt'需要一個帶有'Floating'實例的類型。嘗試使用'Data中的'genericLength'。而是使用'Num'實例來產生任何類型的List。 –
你的摘要是不正確的。類型類不是類型。您不能將數值從Int轉換爲Int,或將Int轉換爲Floating。這些是蘋果和桔子。類型類約束一個類型。例如,您可能有'Floating a => a - > a - > a''這表示'a'必須有一個Floating實例。 '浮動'確實,'詮釋'不。 – erisco
@erisco,這個觀點是'type inference',我的措詞可能會誤導你想'type class'和'type'之間的轉換等。 – sof