簡體   English   中英

為什么這個Haskell表達式編譯?

[英]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.

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