2013-05-29 111 views
19

我有一個關於如何GHCi假定整數的類型的問題。Haskell:是沒有類型的類。爲什麼是整數?

我在讀Yes-No type class瞭解你一個Haskell。

這是一個鏈接,如果你想閱讀整個事情。 http://learnyouahaskell.com/making-our-own-types-and-typeclasses#a-yes-no-typeclass

簡而言之,本章說明了通過定義我自己的類,我可以創建一個可以處理很多類型的函數。

這本書定義YESNO類與功能

yesno :: a -> Bool 

,並Int作爲YESNO類

instance YesNo Int where 
    yesno 0 = False 
    yesno _ = True 

的實例。當我裝這對我GHCI和類型

yesno 0 

它返回錯誤。我認爲這可能是因爲GHCi無法分辨0是否意味着IntIntegerDoubleNum類中的其他類型。實際上,當我輸入yesno(0 :: Int)它工作。

所以只是爲了好玩我做了IntegerYesNo類的一個實例,寫

​​

(請注意,我翻true和false) 又一次,我打字

yesno 0 

(不任何類型的聲明),那麼GHCi顯示True

而且,當我輸入

yesno $ fromIntegral 0 

它返回True,這意味着GHCI認爲的fromIntegral 0類型是Integer

那麼,這是否意味着,當我剛鍵入GHCI一個整數,它通常假定它的值是在代替Integer?我很困惑,因爲​​3210回報Num a => a

回答

24

這是defaulting類型連同ghci中的擴展默認規則。

整數文字是多態的,它們的類型爲Num a => a(因爲它們代表fromInteger literal)。但是,當表達式應該被評估 - 例如打印其結果所必需的 - 表達式必須被賦予一個單形式。

其本身而言,

yesno 0 

強加給0兩個約束Num aYesNo a,並且整個表達將具有不明確的類型

yesno 0 :: (Num a, YesNo a) => Bool 

(這是模糊的,因爲在類型變量約束無法從=>右側的類型中獲得)。

一般來說,曖昧的類型是類型錯誤,但是,在某些情況下,不確定性是用默認類型實例化約束類型變量解決。在語言規範的規則是一個類型變量可以默認如果

在一個不明確的類型被發現的情況下,不明確的類型變量,v,是違約如果:

- `v` appears only in constraints of the form `C v`, where `C` is a class, and 
- at least one of these classes is a numeric class, (that is, `Num` or a subclass of `Num`), and 
- all of these classes are defined in the Prelude or a standard library (Figures 6.2–6.3 show the numeric classes, and Figure 6.1 shows the classes defined in the Prelude.) 

約束(Num a, YesNo a)滿足前兩個要求,但不是第三個要求。所以按照語言標準,它不是可以違約的,應該是一個類型錯誤。

然而,ghci中使用擴展的默認規則,並且還通過在前奏或標準庫不定義的類約束默認類型的變量。

然後,它會選擇這裏Num約束默認情況下,除非明確的默認聲明是在範圍,這將是Integer,或者,如果Integer不滿足約束,Double受審。

因此,當你有一個instance YesNo Integer,ghci可以成功地將類型變量a默認爲Integer。但沒有可用的這樣的情況下,默認失敗,因爲沒有默認的候選人有一個實例。

在第一種情況下
8

那麼,這是否意味着,當我剛鍵入GHCI一個整數,它通常假定它的值是整型?

是的。基本上,GHCI將首先嚐試Integer,如果失敗,Double然後最後()來解析不明確的類型約束。你可以read the details about how this works in the GHC User's Guide

但是,請注意,在編譯的模塊,這些規則都有點嚴格。特別是,只有默認適用於標準類,所以你的例子不是沒有類型註釋的編譯的模塊中,除非您啓用ExtendedDefaultRules擴展,爲您提供了相同的行爲GHCI工作。

1

嘗試寫:

Prelude> yesno (0 :: Int) 
False 
相關問題