作为自由 monad 的 identity monad

The identity monad as a free monad

identity monad的仿函数可以定义为:

data Identity a = Identity a

因为这个 monad 是免费的,所以另一种定义如下:

data Term f a = Pure a | Impure (f (Term f a))

data Zero a

type IdentityF a = Term Zero a

因为这是用两种方式定义的同一个 monad,所以它们应该是 相互转换。也就是说一个人应该能够定义两个 函数 f :: Identity a -> IdentityF ag :: IdentityF a -> Identity a 使得它们的组合 f . gg . f 是 身份。函数f很容易定义:

f :: Identity a -> IdentityF a
f (Identity a) = Pure a

但是函数 g 呢?

g :: IdentityF a -> Identity a
g (Pure a) = Identity a
g (Impure x) = ??????

g (Impure x) 的值应该是多少?我可以试着作弊说出来 是 undefinedf . g 将不是身份函数并且 IdentityIdentityF 不会是同构的。

一个合适的定义是:

g (Impure x) = case x of

case 中没有分支机构。这不是错字。根据需要,case 中的分支与 Zero a 中的构造函数一样多;这是一个完整的模式匹配。

(您必须打开 GHC 的 EmptyCase 扩展才能接受此 as-is。)