簡體   English   中英

Haskell在“ Num”實例上進行划分

[英]Division in Haskell on `Num` instances

請考慮以下GHCI摘錄:

Prelude> :t sum [1,2,3]
sum [1,2,3] :: Num a => a
Prelude> :t fromIntegral (length [1,2,3])
fromIntegral (length [1,2,3]) :: Num b => b
Prelude> :t sum [1,2,3] / fromIntegral (length [1,2,3])
sum [1,2,3] / fromIntegral (length [1,2,3]) :: Fractional a => a

我知道sum [1,2,3]fromIntegral (length [1,2,3])都是Num實例。 讓我感到困惑的是,為什么編譯器將操作數轉換為Fractional 我認為數字轉換必須在Haskell中是明確的。

謝謝!

我認為數字轉換必須在Haskell中是明確的。

沒錯,但是這里我們有數字文字 如果你寫2 ,是不是本身的Int ,或Integer 我們當時還不知道。

例如,如果我們寫2 / 3 ,那么Haskell將得出我們使用函數(/) :: Fractional a => a -> a -> a ,因此得出結論23應該是Fractional 。情況下,它將使用浮點解析器來解析2文字。

但是,如果您明確聲明2是一個Int ,那么它將出錯:

Prelude> (2 :: Int) / 3

<interactive>:4:1: error:
    • No instance for (Fractional Int) arising from a use of ‘/’
    • In the expression: (2 :: Int) / 3
      In an equation for ‘it’: it = (2 :: Int) / 3

因此,通過強制Haskell使用Int ,Haskell看不出將其解析為支持(/)函數的類型的方法。

現在,如果我們分析sum [1,2,3] ,則使其更針對您的問題。 sum類型為sum :: Num a => [a] -> a ,因此,如果列表中的元素為Fractional ,則sum ...也為Fractional類型。

對於分母,您實際上進行了顯式轉換。 實際上,您是寫fromIntegral (length [1,2,3]) 現在length :: [a] -> Int返回一個Int fromIntegral會將任何Integral類型轉換為通用Num類型。 因此它可以將Int轉換為Float

暫無
暫無

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

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