作为自由 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 a
和 g :: IdentityF a -> Identity a
使得它们的组合 f . g
和 g . 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)
的值应该是多少?我可以试着作弊说出来
是 undefined
但 f . g
将不是身份函数并且
Identity
和 IdentityF
不会是同构的。
一个合适的定义是:
g (Impure x) = case x of
case
中没有分支机构。这不是错字。根据需要,case 中的分支与 Zero a
中的构造函数一样多;这是一个完整的模式匹配。
(您必须打开 GHC 的 EmptyCase
扩展才能接受此 as-is。)
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 a
和 g :: IdentityF a -> Identity a
使得它们的组合 f . g
和 g . 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)
的值应该是多少?我可以试着作弊说出来
是 undefined
但 f . g
将不是身份函数并且
Identity
和 IdentityF
不会是同构的。
一个合适的定义是:
g (Impure x) = case x of
case
中没有分支机构。这不是错字。根据需要,case 中的分支与 Zero a
中的构造函数一样多;这是一个完整的模式匹配。
(您必须打开 GHC 的 EmptyCase
扩展才能接受此 as-is。)