我很好奇通過「FlexibleInstances」可以在Haskell的類型類中完成什麼樣的「重載」。可以通過FlexibleInstances「重載」返回不同類型,還是匹配類型類?
作爲一個簡單的測試,這裏是AdjusterType數據類型的一個例子。它定義了一個adjust
操作,將根據是否包含一個整數或雙不同的量添加到它的價值:
{-# LANGUAGE FlexibleInstances #-}
class Adjustable a where
adjust :: a -> Double
data AdjusterType a = Adjuster a
deriving Show
instance Adjustable (AdjusterType Integer) where
adjust (Adjuster a) = fromIntegral (a + 20)
instance Adjustable (AdjusterType Double) where
adjust (Adjuster a) = a + 0.04
說得多按預期工作:
Prelude> adjust (Adjuster (1000 :: Integer))
1020.0
Prelude> adjust (Adjuster (3 :: Double))
3.04
是否有可能使Integer版本的adjust
返回一個Integer,而Double版本返回一個Double?
歸納的adjust
簽名和所述整數的情況下去除所述fromIntegral
不起作用:
class Adjustable a where
adjust :: Num n => a -> n
instance Adjustable (AdjusterType Integer) where
adjust (Adjuster a) = a + 20
這產生一個錯誤說,「n」是一個剛性的類型的變量不匹配整數:
Couldn't match expected type ‘n’ with actual type ‘Integer’
‘n’ is a rigid type variable bound by
the type signature for adjust :: Num n => AdjusterType Integer -> n
Relevant bindings include
adjust :: AdjusterType Integer -> n
In the first argument of ‘(+)’, namely ‘a’
In the expression: a + 20
是期待它什麼類型這裏整數不匹配......或將沒有類型的實際工作,它只是一個奇怪的錯誤消息?(n爲小寫,所以想必知道這是不是一個數據類型)的實例規格
類型約束也不會出現參加匹配分辨率:
instance Integral i => Adjustable (AdjusterType i) where
adjust (Adjuster a) = fromIntegral (a + 20)
instance RealFloat r => Adjustable (AdjusterType r) where
adjust (Adjuster a) = a + 0.04
因此,這些行爲像重複,就好像它們都是Adjustable (AdjusterType x))
。約束僅適用於解決方案完成後。
有沒有什麼辦法可以像上面那樣向類型類提供重載行爲,或者它是否必須總是針對特定的實例?
你想使用該[類型系列(https://downloads.haskell.org/~ghc/latest/docs/html/users_guide/type-families.html)。 – Bakuriu