2017-03-16 59 views
0

我可以創建一個Num a => a這樣的:Num特別這樣嗎?

foo :: Num a => a 
foo = 2 

同樣,對於其他任何數量的類:

foo :: Fractional a => a 
foo = 2.0 

但是,我不能想辦法創造Eq a => a型,Ord a => a的東西,或任何非數字(不使用undefined)。

在我看來,這種數字是特殊的。

他們是?

+1

數字文字是'fromInteger'和'fromRational'的特殊語法 - 您可以創建一個'Num a => a'類型的值,因爲您有一個函數'f :: Num a => .. - > a' (即'fromInteger')。對於任何其他類型類型,這也是一樣的。 「Eq」或「Ord」沒有這樣的函數,即返回類型中帶有typeclass參數。 – user2407038

回答

6

Num並不是「特殊的」,因爲它是唯一的表現方式。但它確實有一些使它成爲可能的特徵。請考慮使用Bounded類型類型。這是完全可以定義一個類似的功能:

top :: Bounded a => a 
top = maxBound 

這是可能的,因爲Bounded,像Num但不像Eq,提供作爲其類定義的一部分的方式來創建其類型的值。

1

Num是特別的,它具有寫文字的特殊語法。該語法在內部使用功能fromInteger :: Num a => Integer -> a,該功能在Num中定義。編譯器將您寫入的內容解析爲Integer,並將其輸入fromInteger以獲取您看到的類型。

你不能這樣做的原因,例如Eq a => aEq沒有函數返回該類型的東西。

如果你真的需要這樣的值,你可以使用類似data Equatable = forall e. Eq e => MkEquatable e的東西使用ExistentialQuantification擴展,但這可能不是你想要做的。

這裏是一個類型的類的實例,而您可以用MyClass a => a類型創建一個值:gist

+1

除了關於存在之外,似乎可能會造成混淆,甚至似乎沒有關係,因爲問題是關於共相。 –

+0

如果你在MkEquatable模式匹配,裏面的變量將有類型'Eq a => a'。既然他們特別問這是否可能,我想確保我覆蓋了所有的可能性。 – Lazersmoke

+0

它當然不會。如果是這樣的話,你可以將任何'Eq'實例的值轉換爲任何其他'Eq'實例的值;例如'MkEquatable True'是很好的類型,所以如果'unEquatable :: Equatable - >(Eq a => a); unEquatable(MkEquatable e)= e'就像你說的那樣是很好的類型,那麼'unEquatable(MkEquatable True):: String'將是很好的類型,但顯然是無稽之談。 –

5

還有更多的例子:

def :: Default a => a 
mempty :: Monoid a => a 
maxBound :: Bounded a => a 
toEnum 0 :: Enum a => a 
read "" :: Read a => a 
fromString "" :: IsString a => a 

這只是我的頭頂部。我相信還有更多。