好吧,這個人一直在嘮叨我。考慮到各種情況下的, 讓我們去整個生豬和擺脫不是一個實例存在其他的 源和目標類型之間的關係:
{-# LANGUAGE OverlappingInstances, FlexibleInstances,TypeSynonymInstances,MultiParamTypeClasses #-}
class Foo a b where f :: a -> b
現在我們可以匹配對類型它們之間的f
但是我們喜歡,例如:
instance Foo Int Int where f = (+1)
instance Foo Int Integer where f = toInteger.((7::Int) -)
instance Foo Integer Int where f = fromInteger.(^ (2::Integer))
instance Foo Integer Integer where f = (*100)
instance Foo Char Char where f = id
instance Foo Char String where f = (:[]) -- requires TypeSynonymInstances
instance (Foo a b,Functor f) => Foo (f a) (f b) where f = fmap f -- requires FlexibleInstances
instance Foo Float Int where f = round
instance Foo Integer Char where f n = head $ show n
這也意味着大量的顯式類型註解,以避免No instance for...
和Ambiguous type
錯誤消息。 例如,你不能這樣做main = print (f 6)
,但你可以做main = print (f (6::Int)::Int)
你可以列出所有你想要的標準類型, 這可能導致一個可怕的很多重複的實例,我們的你可以照亮藍色Touchpaper的和做的事:
instance Integral i => Foo Double i where f = round -- requires FlexibleInstances
instance Real r => Foo Integer r where f = fromInteger -- requires FlexibleInstances
請注意:這並不不意味着「嘿,如果你有一個整體式i
, 你用這個方便的可以有一個實例Foo Double i
免費功能全面「 它的意思是:」 每時候你有任何類型i
,這絕對是一個實例 Foo Double i
。順便說一下,我爲此使用了round
,所以除非您的類型i
是Integral
, 我們會掉線。「例如,這對於Foo Integer Char
實例來說是一個大問題。
這很容易破壞你的其他情況,所以如果你現在輸入f (5::Integer) :: Integer
你
Overlapping instances for Foo Integer Integer
arising from a use of `f'
Matching instances:
instance Foo Integer Integer
instance Real r => Foo Integer r
你可以改變你的pragma包括OverlappingInstances:
{-# LANGUAGE OverlappingInstances, FlexibleInstances,TypeSynonymInstances,MultiParamTypeClasses #-}
所以現在f (5::Integer) :: Integer
回到500,所以顯然它使用更具體的Foo Integer Integer
實例。
我認爲這種方法可能適用於您,手動定義多個實例,仔細考慮何時完全通配 使實例脫離標準類型類。 (或者,並非所有的標準類型都是如此,衆所周知,notMany choose 2 = notIntractablyMany
,因此您可以將它們全部列出。)
當您說'class AllowedParamType a c | a - > c',你說給定任何類型'a'作爲第一個參數,最多隻有一個類型'c'可以用作第二個參數。但是當你說第一個類型是一個'Integral'類型時,*任何*'Real'類型都可以用作第二個參數。理想情況下,GHC會給你一個錯誤信息指出這一點。 – dave4420
這不是真的。它只是意味着一個唯一的確定b允許以上類型的實例。 – Satvik
Satvik是對的,fundep *的獨特性不應該是導致代碼不能編譯的原因。然而,dave4420也有一個正確的想法:從長遠來看,fundep不會起作用,因爲我不想將Int的參數類型限制爲整個程序的一種Real。 – crockeea