如何为自由幺半群(Free Monoid)定义超类约束?
自由幺半群类型类的约束问题
首先定义针对自由幺半群的类型类:
class FreeMonoid f where inj :: a -> f a univ :: Monoid m => (a -> m) -> f a -> m
其中:
inj用于将值注入自由幺半群univ对应自由幺半群的泛性质
该类型类的实例需要满足以下定律:
- 恒等律(Identity):
univ f . inj = f - 空元律(Free empty):
univ f mempty = mempty - 结合律(Free append):
univ f (m <> n) = univ f m <> univ f n
需要注意的是:若f是FreeMonoid的实例,那么(f a)必须是Monoid的实例,否则后两条定律没有实际意义。但如何正确在类型类中指定这个约束?
我尝试过这样的写法:
class Monoid (f a) => FreeMonoid f where inj :: a -> f a univ :: Monoid m => (a -> m) -> f a -> m
如果缺少这个约束,使用类型类时会非常不便。比如下面这个函数:
mapFreeMonoid :: (FreeMonoid f, Monoid (f b)) => (a -> b) -> f a -> f b mapFreeMonoid f = univ (inj . f)
既然f已经是FreeMonoid的实例,理论上不应该再额外指定Monoid (f b)约束,理想的函数定义应该是这样:
mapFreeMonoid :: FreeMonoid f => (a -> b) -> f a -> f b mapFreeMonoid f = univ (inj . f)
内容的提问来源于stack exchange,提问作者Aadit M Shah
相关产品推荐
相关产品推荐

