这个“Coapplicative”类是 Comonad 的超类吗?

问题描述 投票:0回答:1

回忆一下

Applicative
课程:

class Functor f => Applicative f where
    pure :: a -> f a
    liftA2 :: (a -> b -> c) -> f a -> f b -> f c
    (<*>) :: f (a -> b) -> f a -> f b

    liftA2 h x y = fmap h x <*> y
    (<*>) = liftA2 id

虽然目前还不清楚如何用(数学)范畴论来表达这个类,但当定义以下函数时就会变得清晰:

liftZ2 :: Applicative f => (f a, f b) -> f (a, b)
liftZ2 (x, y) = liftA2 (,) x y

在这里,

(,)
应该可以被识别为分类产品。用余积替换积并反转所有箭头给出以下类别:

class Functor f => Coapplicative f where
    copure :: f a -> a
    coliftZ2 :: f (Either a b) -> Either (f a) (f b)

一些实例:

import Data.Functor.Identity
import qualified Data.List.NonEmpty as NonEmpty
import Data.Either

instance Coapplicative Identity where
    copure (Identity x) = x
    coliftZ2 (Identity (Left x)) = Left (Identity x)
    coliftZ2 (Identity (Right y)) = Right (Identity y)

instance Coapplicative NonEmpty.NonEmpty where
    copure (x NonEmpty.:| _) = x
    coliftZ2 (Left x NonEmpty.:| xs) = Left (x NonEmpty.:| lefts xs)
    coliftZ2 (Right y NonEmpty.:| ys) = Right (y NonEmpty.:| rights ys)

instance Coapplicative ((,) e) where
    copure (_, x) = x
    coliftZ2 (e, Left x) = Left (e, x)
    coliftZ2 (e, Right y) = Right (e, y)

instance Monoid m => Coapplicative ((->) m) where
    copure f = f mempty
    coliftZ2 f = case copure f of
        Left x -> Left (fromLeft x . f)
        Right y -> Right (fromRight y . f)

我有一种强烈的直觉,

Coapplicative
Comonad
的超类,但我不知道如何证明它。另外,是否有一个
Coapplicative
实例不是
Comonad

haskell functor applicative comonad
1个回答
0
投票

这不是一个完整的答案,但我至少可以证明你的

Coapplicative NonEmpty
实例不能单独从
Comonad
方法派生;也就是说,如果有一些参数化的实现

coliftZ2 :: (Comonad w) => w (Either a b) -> Either (w a) (w b)

那么它不会为

NonEmpty
生成您的实例。这是因为
Comonad
本身不允许我们以任何方式更改列表的长度——事实上,所有固定长度向量都是共元,但
NonEmpty
coliftZ2
实例会改变长度。因此,如果
NonEmpty
要成为
Coapplicative
,它必须以其他方式实现。


我需要去睡觉了,但我想说探索 comonad 是值得的

data Two a = Two a a
    deriving (Functor)

instance Comonad Two where
    extract (Two x _) = x
    duplicate (Two x y) = Two (Two x y) (Two y x)

并考虑其

coliftZ2
的实施必须是什么。你还没有给出
Coapplicative
的任何定律,但如果你这样做了,我怀疑这将是一个很好的反例,因为我发现
coliftZ2
没有实现令人满意的对称性。这两个方程都相当牵强,但它们似乎表明了运算的非常不同的含义。

coliftZ2 (Two (Left x) (Left y)) = Left (Two x y)
coliftZ2 (Two (Left x) (Right y)) = Left (Two x x)
© www.soinside.com 2019 - 2024. All rights reserved.