我很好奇通过“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