[英]Overloaded / Polymorphic Functions with different types
我正在學習 Haskell 並遇到了一個懸而未決的問題:
從我正在學習的課程中:
(+) :: Num a => a -> a -> a
對於任何數值類型
a
,(+)采用類型的2個值a
並返回類型的值a
。
根據示例:
1 + 1
-- 2 # type a is Int
3.0 + 4.0
-- 7.0 type a is Float
'a' + 'b'
-- Type Error: Char is not a Numeric type
這是完全有道理的,但我最終不明白后台發生了什么,當:
1 + 3.0
類型推斷系統是否會自動將我的 Int 轉換為 Float,因為它知道它將返回 Float?
您應該在 ghci 中調查此類問題。 這是一個非常寶貴的學習資源:
$ ghci
GHCi, version 9.0.1: https://www.haskell.org/ghc/ :? for help
ghci> :t 1
1 :: Num p => p
ghci> :t 3.0
3.0 :: Fractional p => p
ghci> :t 1 + 3.0
1 + 3.0 :: Fractional a => a
第一課:數字文字是多態的。 1
不是Int
,它是多態的。 它可以是代碼編譯所需的任何Num
實例。 3.0
不是Float
,而是代碼編譯所需的任何Fractional
實例。 (區別在於文字中的小數點 - 它限制了允許的類型。)
第二課:當你將事物組合成一個表達式時,類型就會統一。 當您統一Num
和Fractional
約束時,您會得到一個Fractional
約束。 這是因為Fractional
被定義為要求它的所有實例也是Num
實例。
更多信息,讓我們打開警告,看看它們提供了哪些附加信息。
ghci> :set -Wall
ghci> 1
<interactive>:5:1: warning: [-Wtype-defaults]
• Defaulting the following constraints to type ‘Integer’
(Show a0) arising from a use of ‘print’ at <interactive>:5:1
(Num a0) arising from a use of ‘it’ at <interactive>:5:1
• In a stmt of an interactive GHCi command: print it
1
ghci> 1 + 3.0
<interactive>:6:1: warning: [-Wtype-defaults]
• Defaulting the following constraints to type ‘Double’
(Show a0) arising from a use of ‘print’ at <interactive>:6:1-7
(Fractional a0) arising from a use of ‘it’ at <interactive>:6:1-7
• In a stmt of an interactive GHCi command: print it
4.0
打印值時,ghci 要求類型具有Show
實例。 幸運的是,這里的細節並不是很重要,但這就是默認警告引用Show
。
這里要觀察的教訓是,如果推理不需要更具體的東西,那么帶有Num
實例的東西的默認類型是Integer
,而不是Int
。 如果推理不需要更具體的東西,那么帶有Fractional
實例的東西的默認類型是Double
,而不是Float
。 ( Float
基本上從未使用過。忘記它存在。)
因此,當推理運行時,表達式1 + 3.0
被推斷為具有Fractional a => a
類型。 在對類型沒有進一步要求的情況下,默認啟動並說“ a
is Double
”。 然后該信息通過(+)
流回其參數,並要求它們中的每一個也是Double
。 幸運的是,每個參數都是一個可以采用Double
類型的多態文字。 類型檢查成功,選擇實例,發生加法,打印結果。
對於這個過程來說,數字文字是多態的非常重要。 Haskell 沒有任何類型對之間的隱式轉換。 尤其不是數字類型。 如果您想真正將值從一種類型轉換為另一種類型,您必須調用一個函數來進行您想要的轉換。 ( fromIntegral
、 round
、 floor
、 ceiling
和realToFrac
是最常見的數值轉換函數。)但是當值是多態時,這意味着推理可以選擇匹配類型而無需轉換。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.