我想我已经为Free
找到了一个有趣的“zippy”Applicative
示例。
data FreeMonad f a = Free (f (FreeMonad f a))
| Return a
instance Functor f => Functor (FreeMonad f) where
fmap f (Return x) = Return (f x)
fmap f (Free xs) = Free (fmap (fmap f) xs)
instance Applicative f => Applicative (FreeMonad f) where
pure = Return
Return f <*> xs = fmap f xs
fs <*> Return x = fmap ($x) fs
Free fs <*> Free xs = Free $ liftA2 (<*>) fs xs
这是一种zip-longest策略,例如,使用data Pair r = Pair r r
作为函子(所以FreeMonad Pair
是一个外部标记的二叉树):
+---+---+ +---+---+ +-----+-----+
| | | | <*> | |
+--+--+ h x +--+--+ --> +--+--+ +--+--+
| | | | | | | |
f g y z f x g x h y h z
我以前没有看到任何人提到过这个示例。它是否违反了任何Applicative
法则?(当然,它与通常的Monad
示例不一致,后者是“substitutey”而不是“zippy”)。
3条答案
按热度按时间zfciruhq1#
是的,看起来这是一个合法的
Applicative
。奇怪!正如@JosephSible所指出的,你可以从定义中立即读出恒等、同态和交换定律。唯一棘手的是合成定律。
有八个箱子要检查,所以系好安全带。
Return
:pure (.) <*> Return f <*> Return g <*> Return z
(.)
的结合性可以得出。Free
:pure (.) <*> Free u <*> Return g <*> Return z
Free u <*> (Return g <*> Return z)
向后计算得到fmap (\f -> f (g z)) (Free u)
,所以这是由函子定律得出的。pure (.) <*> Return f <*> Return g <*> Free w
fmap (f . g) (Free w)
,所以从函子定律得出。Return
:Free
:pure (.) <*> Free u <*> Free v <*> Free w
<*>
的Free
/Free
的情况,其右侧与Compose
的<*>
的右侧相同,所以本例是从Compose
的示例的正确性出发得出的。对于
pure (.) <*> Free u <*> Free v <*> Return z
的情况,我使用了一个引理:引理:
fmap f (fmap g u <*> v) = liftA2 (\x y -> f (g x y)) u v
。在归纳假设下,我使用函子和应用定律。
这证明起来非常有趣!我希望看到Coq或Agda的正式证明(尽管我怀疑终结/积极性检查器可能会把它搞砸)。
x9ybnkn62#
For the sake of completeness, I will use this answer to expand on my comment above:
Though I didn't actually write down the proof, I believe the mixed-Free-and-Return cases of the composition law must hold due to parametricity. I also suspect that should be easier to show using the monoidal presentation .
The monoidal presentation of the
Applicative
instance here is:Under the monoidal presentation, the composition/associativity law is:
Now let's consider one of its mixed cases; say, the
Free
-Return
-Free
one:Let's have a closer look at this left-hand side.
(,y) <$> Free fu
applies(,y) :: a -> (a, b)
to thea
values found inFree fu :: FreeMonad f a
. Parametricity (or, more specifically, the free theorem for(*&*)
) means that it doesn't matter if we do that before or after using(*&*)
. That means the left-hand side amounts to:Analogously, the right-hand side becomes:
Since
first (,y) :: (a, c) -> ((a, b), c)
andsecond (y,) :: (a, c) -> (a, (b, c))
are the same up to reassociation of pairs, we have:The other mixed cases can be dealt with analogously. For the rest of the proof, see Benjamin Hodgson's answer .
wgx48brx3#
由
Applicative
的定义可知:如果
f
也是Monad
,则应满足(<*>)
=ap
(*>)
=(>>)
因此,这种实现将违反适用法律,即它 * 必须 * 与
Monad
示例一致。也就是说,没有理由不能为
FreeMonad
创建一个newtype Package 器,它没有monad示例,但有上面的applicative示例