[英]Why does this Haskell expression compile?
以下是我寫的一些定義,以避免混合貨幣
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
data EUR
data USD
newtype Amount a = Amount Double deriving (Fractional, Num, Show)
eur :: Double -> Amount EUR
eur = Amount
usd :: Double -> Amount USD
usd = Amount
usd 34 + usd 3
類型檢查按預期 usd 33 + eur 33
是預期的編譯錯誤 usd 33 + 3
是可以的。 我想避免的東西,並且不明白。 我懷疑這是因為Num
實例,但那么第二種情況有什么不同? 你能解釋一下為什么我們usd 33 + 3
編譯,如果有可能使類型檢查器拒絕這個表達式。
Haskell中的數字有很多隱含性。 在心理上,你應該用fromInteger 3
替換像3
這樣的每個數字。 由於Amount
使用GeneralizedNewtypeDeriving
作為Num
類型類的一部分,因此它繼承了一個fromInteger
實例。 所以編譯器正在這樣做
usd 33 + 3
=== [implicit fromInteger & expand usd]
(Amount 33 :: Amount USD) +
fromInteger 3
=== [fromInteger :: Num a => a -> Amount a]
(Amount 33 :: Amount USD) +
(Amount 3 :: Amount a)
=== [unify a]
(Amount 33 :: Amount USD) +
(Amount 3 :: Amount USD)
當GHC派生Num
類時,它為fromInteger
函數提供了一個實現。 像3
這樣的整數文字實際上具有類型Num a => a
。
ghci> :t (34)
(34) :: Num a => a
當類型檢查器發現您嘗試將Amount USD
類型的值添加到3
,它確定3 :: Amount USD
,這是有效的,因為它是Num
類型類的成員。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.