2015-04-15 26 views
4

在試圖理解Haskell中的實例時,我做了這個例子。整數部分工作正常,但不適用於Float實例。我認爲最好是創建一個Num類型的單個實例(以便在所有Num上使用正方形)。我想我必須將Num作爲約束添加到我的類聲明中,但我無法弄清楚實例的外觀。據我瞭解,對類的約束迫使任何實例屬於這種類型(根據約束)。Haskell。使用約束來定義類的實例

class Square a where 
    area :: a -> a 

instance Square Integer where 
    area a = a*a 

instance Square Float where 
    area a = a*a 
+1

'Square Float'實例應該可以正常工作。你遇到了什麼問題? – leftaroundabout

+1

上面的代碼應該適用於Float。你應該只打電話,例如區域10.0 :: Float去除不明確性。 –

回答

10

我覺得這是更好地使類型Num的單個實例...

不是真的,除非你要定義一個類Num類型(和那麼你根本不需要任何課程,只需將其作爲頂級功能area :: Num a => a->a即可)。

下面就來做出這樣的泛型實例的方式:

instance (Num a) => Square a where 
    area a = a*a 

這不是Haskell98,但它與目前廣泛使用的-XFlexibleInstances-XUndecidableInstances擴展工作。

問題:如果你還再要添加,比如說,

instance Square String where 
    area str = concat $ replicate (length str) str 

你有兩個重疊的情況下。這是一個問題:一般來說,編譯器無法確定哪兩個這樣的實例是正確的。再次,GHC有擴展來做出最佳猜測(-XOverlappingInstances-XIncoherentInstances),但不像Flexible/UndecidableInstances這些是generally avoided

所以我建議使單個實例Square IntSquare IntegerSquare Double。他們不是很難寫,是嗎?