向 Monad 结果类型添加约束

Adding a Constraint to a Monad Result Type

我想创建一个类型,它是 Monad 的实例,这样结果类型只能是特定类型类的实例。我希望能够写出类似

的东西
data T a = T a
class C a where
    ...

instance Monad T where
    return :: (C a) => a -> m a
    return x = ...
    (>>=) :: (C a, C b) => m a -> (a -> m b) -> m b
    p >>= f = ...

在我正在处理的实际代码中,我需要对结果类型进行类型类约束,以便类型类中的特定函数在 return(>>=) 的定义中可用. 有什么办法吗?

根据@chi 的评论,最好的解决方案可能是使用约束 monad 或索引 monad。这两种解决方案都有一个警告,即必须绕过标准库,但可以通过变通办法来完成,例如使用 RebindableSyntax 扩展名重新绑定语法。我能找到的受约束单子的最好例子是 constrained-monads package available on Hackage, while the best example I was able to find of indexed monads was a post at Kwang's Haskell Blog.