想象一下,我有一个在 monad 上通用的值:
m :: (Monad m) => m A -- 'A' is some concrete type
现在假设我以两种不同的方式将此值专门用于具体的 monad 转换器堆栈:
m1 :: T M A
m1 = m
m2 :: T M A
m2 = lift m
...其中M
和T M
是单子,并且T
是单子转换器:
instance Monad M where ...
instance (Monad m) => Monad (T m) where ...
instance MonadTrans T where ...
...并且这些实例遵守单子定律和单子变换器定律。
我们可以推断出:
m1 = m2
m
...除了它的类型之外一无所知?
这只是一个冗长的询问是否lift m
是 的有效替换的方式m
,假设两者都进行了类型检查。表述这个问题有点困难,因为它需要m
在替换之前和之后将类型检查作为两个单独的 monad。据我所知,这种替换类型检查的唯一方法是 ifm
对 monad 是通用的。
我模糊的直觉是替换应该总是正确的,但我不确定我的直觉是否正确,或者如果它是正确的,如何证明它。