将Functor类扩展为MultiFunctor?

时间:2019-01-13 09:23:45

标签: haskell functor applicative

我正在从“ video”中学习。当然,我要问的问题在本文的主要思想方面还是一个问题,但仍然...

...在第6页上,尝试将Functor概括为MultiFunctor

class Functor f ⇒ MultiFunctor f where
    fmap0 :: a → f a
    fmap1 :: (a → b) → f a → f b
    fmap1 = fmap
    fmap2 :: (a → b → c) → f a → f b → f c
    ...

从类别理论的角度来看,我看不出该定义的合理性:fmap2似乎只是一个双重功能,即在Free Applicative Functors上定义的函子。根据定义,产品类别由所有可能的有序对象对给定,并且态射也是成对的,因此:fmap2 :: (a -> a', b -> b') -> (f a, f b) -> (f a', f b')的外观和感觉更合适。

我可以理解(a -> b -> c) -> f a -> f b -> f c选择后的思维方式:这是采用已知(a -> b) -> f a -> f b签名并强制其与二进制函数(而不是一元函数)一起使用的最明显的方法。但是MultiFunctor(通过上面的定义给出)实际上是类别理论所期望的双向/多重功能吗?

P.S。我感到好奇的原因是,似乎{strong>不能通过概括Applicative进入Functor,尽管论文指出可以。

2 个答案:

答案 0 :(得分:6)

我认为您所采用的范畴理论角度是错误的。有一个Bifunctor类(映射类型为(a -> b) -> (c -> d) -> f a c -> f b d),但这不是这种概括。如果一个人没有使用某些功能,则fmap2的签名如下:

fmap2 :: ((a,b) -> c) -> (f a, f b) -> f c

通过考虑fmap2 id,我们看到我们实现的不是bifunctor,而是笛卡尔函子(即笛卡尔类别之间的单等函子),其中fmap2 id :: (f a, f b) -> f (a,b)是自然变换:

\mu_{x,y} : F(x) \otimes F(y) \to F(x \otimes y)

然后可以从此Multifunctor概括中获得适用性。只需将pure的{​​{1}}更改为fmap0的{​​{1}}。

答案 1 :(得分:2)

让我们从显而易见的内容开始:fmap0是纯粹的。

您在这里犯了一个错误:fmap2liftA2

({bimap非常不同-(a -> b) -> (c -> d) -> f a b -> f c d

如果返回到definition of Applicative,您会看到它具有(<*>)的默认实现,即liftA2 id,它允许您以纯净和liftA2(<*>)

是的,该类等效于Applicative