Haskell 证明自由单体的函子定律;我做得对吗?
我很难理解如何证明自由单子的Haskell 证明自由单体的函子定律;我做得对吗?,haskell,monads,proof,free-monad,Haskell,Monads,Proof,Free Monad,我很难理解如何证明自由单子的函子和单子定律。首先,让我给出我正在使用的定义: data Free f a = Pure a | Free (f (Free f a)) instance Functor f => Functor (Free f) where fmap f (Pure a) = Pure (f a) fmap f (Free fa) = Free (fmap (fmap f) fa) instance Functor f => Monad (Free
函子
和单子
定律。首先,让我给出我正在使用的定义:
data Free f a = Pure a | Free (f (Free f a))
instance Functor f => Functor (Free f) where
fmap f (Pure a) = Pure (f a)
fmap f (Free fa) = Free (fmap (fmap f) fa)
instance Functor f => Monad (Free f) where
return = Pure
Pure a >>= f = f a
Free fa >>= f = Free (fmap (>>=f) fa)
{-
Functor laws:
(1) fmap id x == x
(2) fmap f (fmap g x) = fmap (f . g) x
Monad laws:
(1) return a >>= f == f a
(2) m >>= return == m
(3) (m >>= f) >>= g == m >>= (\x -> f x >>= g)
-}
如果我理解正确,等式证明需要求助于一个共导假设,它或多或少像这个例子:
Proof: fmap id == id
Case 1: x := Pure a
fmap id (Pure a)
== Pure (id a) -- Functor instance for Free
== Pure a -- id a == a
Case 2: x := Free fa
fmap id (Free fa)
== Free (fmap (fmap id) fa) -- Functor instance for Free f
== Free (fmap id fa) -- By coinductive hypothesis; is this step right?
== Free fa -- Functor f => Functor (Free f), + functor law
我强调了我不确定自己是否做对了的步骤
如果该证明是正确的,则第二定律的免费
构造函数案例的证明如下:
fmap f (fmap g (Free fa))
== fmap f (Free (fmap (fmap g) fa))
== Free (fmap (fmap f) (fmap (fmap g) fa))
== Free (fmap (fmap f . fmap g) fa)
== Free (fmap (fmap (f . g)) fa) -- By coinductive hypothesis
== fmap (f . g) (Free fa)
是的,这是正确的。共归纳的“基本情况”是
纯
构造函数,归纳是自由
构造函数的嵌套级别
完整的证据是
-- 1. First functor law
-- a. Base case
fmap id (Pure a) = Pure (id a) -- Functor instance for Free
= Pure a -- definition of id
-- b. Inductive case
fmap id (Free fa) = Free (fmap (fmap id) fa) -- Functor instance for Free
= Free (fmap id fa) -- coinductive hypothesis
= Free fa -- 1st functor law for f
-- 2. Second functor law
-- a. Base case
fmap f (fmap g (Pure a)) = fmap f (Pure (g a)) -- Functor instance for Free
= Pure (f (g a)) -- Functor instance for Free
= Pure ((f . g) a) -- Definition of (.)
= fmap (f . g) (Pure a) -- Functor instance for Free
-- b. Inductive case
fmap f (fmap g (Free fa)) = fmap f (Free (fmap (fmap g) fa)) -- Functor instance for Free
= Free (fmap (fmap f) (fmap (fmap g) fa)) -- Functor instance for Free
= Free (fmap (fmap f . fmap g) fa) -- 2nd functor law for f
= Free (fmap (fmap (f . g) fa)) -- Coinductive hypothesis
= fmap (f . g) (Free fa) -- Functor instance for Free
等等,为什么这是一个共同推导而不是简单无聊的旧归纳法?@DanielWagner如果我理解正确的话,那是因为我们有像
fix(Free.Identity)
这样的案例,它们在任何地方都不包含纯。@ChrisTaylor好的,我有点困惑。如果我们使用共归纳,为什么(b)个案例被标记为“归纳案例”?同样地,对于(a)案例上的“基本案例”标签,我认为“基本案例”意味着有充分的基础,而共归纳没有?它是共归纳,因为它是一种共归纳类型。同一个参数适用于归纳版本的Free
,因为您在锁定步骤中增长结果并收缩参数。称之为“基本情况”有点奇怪。我希望免费是数据,而不是codata。并不是说哈斯凯尔把这些东西小心地分开,或者别的什么,但至少这是我们的目标。