haskell 如何定义自由么半群的超类约束?

7ivaypg9  于 2022-12-29  发布在  其他
关注(0)|答案(2)|浏览(138)

考虑下面的自由么半群的类型类。

class FreeMonoid f where
    inj :: a -> f a
    univ :: Monoid m => (a -> m) -> f a -> m

inj向自由幺半群注入一个值,并且univ是自由幺半群的泛性质。
此类的示例应满足以下规则。

*身份univ f . inj = f
*自由空univ f mempty = mempty
*自由追加univ f (m <> n) = univ f m <> univ f n

注意,如果fFreeMonoid的一个示例,那么(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)

由于fFreeMonoid的一个示例,我们不需要指定Monoid (f b)约束,理想情况下,我们应该能够如下定义上述函数。

mapFreeMonoid :: FreeMonoid f => (a -> b) -> f a -> f b
mapFreeMonoid f = univ (inj . f)
x4shl7ld

x4shl7ld1#

您可以尝试使用QuantifiedConstraints扩展。

class (forall a. Monoid (f a)) => FreeMonoid f where
   ...

然后,您的代码将在没有附加约束的情况下进行编译。

mapFreeMonoid :: FreeMonoid f => (a -> b) -> f a -> f b
mapFreeMonoid f = univ (inj . f)
vnjpjtjt

vnjpjtjt2#

你可以像chi回答的那样使用QuantifiedConstraints扩展,看看自由范畴的类似定义,这里是CFree约束。

相关问题