我定义了以下数据类型:
data Probability a = PD { mass :: [(a, Ratio Int)] }
现在我想写它是一个实例Functor
:
collect :: (Eq a, Num b) => [(a, b)] -> [(a, b)]
collect al = map collect' keys where
keys = nub $ map fst al
collect' k = (k, sum (map snd (matches k)))
matches k = filter ((==) k . fst) al
instance (Eq a) => Functor (Probability a) where
fmap f p = PD (collect $ map (first f) (mass p))
但是,我收到以下错误:
Kind mis-match
The first argument of `Functor' should have kind `* -> *',
but `Probability a' has kind `*'
In the instance declaration for `Functor (Probability a)'
我怎样才能添加必要的Eq a
约束? (我使用的是 GHC 7.4.1)
可悲的是,你不能这样做——Functor
实例必须不受限制地接受任何类型的映射函数。
不过,你可以假装它。
newtype PF a = PF { unPF :: forall r . Eq r => (a -> r) -> Probability r }
instance Functor PF where
fmap f (PF p) = PF (\mp -> p (mp . f))
在这里,所有将被映射的函数Probability
已被“推迟”PF
。我们通过“降低”回到Probability
如果可能
lowerPF :: Eq a => PF a -> Probability a
lowerPF pf = unPF pf id
为了转换Probability
into a fmappable
PF
我们必须“举起”它
liftPF :: Probability a -> PF a
liftPF p = PF $ \mp -> PD (collect $ map (first mp) (mass p))
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)