我通過使用GHCI測試的數字脅迫:如何將Num類型類的實例隱式地強制爲Fractional?
>> let c = 1 :: Integer
>> 1/2
0.5
>> c/2
<interactive>:15:1: error:
• No instance for (Fractional Integer) arising from a use of ‘/’
• In the expression: c/2
In an equation for ‘it’: it = c/2
>> :t (/)
(/) :: Fractional a => a -> a -> a -- (/) needs Fractional type
>> (fromInteger c)/2
0.5
>>:t fromInteger
fromInteger :: Num a => Integer -> a -- Just convert the Integer to Num not to Fractional
我可以使用fromInteger
功能的整數類型轉換爲NUM(fromInteger具有類型fromInteger :: Num a => Integer -> a
),但我不理解如何可以在類型Num
被轉換隱含地到Fractional
?
我知道,如果一個實例的類型是Fractional
必須有類型Num
(class Num a => Fractional a where
),但確實有必要,如果一個實例的類型是Num
它可以被用作一個實例與Fractional
類型?
@mnoronha感謝您的詳細回覆。只有一個問題讓我困惑。我知道type a
不能在功能(/)
中使用的原因是type a
與type Integer
不是type class Fractional
(功能(/)
要求參數類型必須是instance of Fractional
)的實例。我不明白的是,即使通過調用fromInteger
將類型整數轉換爲a
類型(它是Num
的一個實例),它並不意味着a
類型是Fractional
的一個實例(因爲分數類型類比Num類型類更受約束,因此a
類型可能無法實現Fractional type class
所要求的某些功能)。如果a
類型不完全符合Fractional type class
要求的條件,那麼如何在功能(/)
中使用,該函數會將參數類型作爲分數的實例。對不是母語的人抱歉,非常感謝您的耐心等待!
我測試過如果一個類型只適合父類型類,它不能用在需要更多約束類型類的函數中。
{-# LANGUAGE OverloadedStrings #-}
module Main where
class ParentAPI a where
printPar :: int -> a -> String
class (ParentAPI a) => SubAPI a where
printSub :: a -> String
data ParentDT = ParentDT Int
instance ParentAPI ParentDT where
printPar i p = "par"
testF :: (SubAPI a) => a -> String
testF a = printSub a
main = do
let m = testF $ ParentDT 10000
return()
====
test-typeclass.hs:19:11: error:
• No instance for (SubAPI ParentDT) arising from a use of ‘testF’
• In the expression: testF $ ParentDT 10000
In an equation for ‘m’: m = testF $ ParentDT 10000
In the expression:
do { let m = testF $ ParentDT 10000;
return() }
我發現了一個文檔解釋得很清楚數字超載的模糊性和可幫助其他有同樣的困惑。
https://www.haskell.org/tutorial/numbers.html
如果一個類型變量'a'只受限於Num a => a,但不受Fractional類型的約束。那是說變量'a'可能不會實現一些行爲函數,比如'(/)'?如果例如分數行爲函數'(/)'沒有實現,那麼'(/)'函數中可以如何使用'a'? – hliu
我們知道由'Fractional a => a'約束的類型變量將能夠實現'Num'類中定義的所有行爲。反過來也是如此,因爲我們可以將'Fractional a => a'視爲更嚴格的約束 - >可接受的'a'類型是一個子集。 – mnoronha
感謝您的詳細回覆。這裏只有一個問題,但太長了,我在原始問題後發帖。 – hliu