【问题标题】:Why there is no `Cofunctor` typeclass in Haskell?为什么 Haskell 中没有“Cofunctor”类型类?
【发布时间】:2016-04-16 09:55:20
【问题描述】:

Monads 从 Functor 类型类中获得 fmap。为什么comonads 不需要在Cofunctor 类中定义cofmap 方法?

【问题讨论】:

  • 那是因为协函子和函子是一样的。两者没有区别。但是,单子和共子是不同的。不过,有一个逆变函子之类的东西,它有一个contramap 方法,其类型为Contravariant f => (a -> b) -> f b -> f a。但是,它与辅函数不同。
  • 你的意思是“协函子”是函子的对偶(它只是函子,因为它是自对偶的),还是指逆变的函子? math.stackexchange.com/questions/394472/…

标签: haskell monads functor


【解决方案1】:

Functor 定义为:

class Functor f where
    fmap :: (a -> b) -> (f a -> f b)

Cofunctor可以定义如下:

class Cofunctor f where
    cofmap :: (b -> a) -> (f b -> f a)

所以,两者在技术上是相同的,这就是Cofunctor 不存在的原因。 “'一般函子'的双重概念仍然是'一般函子'”。

由于FunctorCofunctor 相同,所以monad 和comonad 都使用Functor 定义。但是不要让你认为单子和共单子是一回事,它们不是。

一个monad被定义(简化)为:

class Functor m => Monad where
    return :: a -> m a
    (>>=) :: m a -> (a -> m b) -> m b

comonad(再次简化)是否是:

class Functor w => Comonad where
    extract :: w a -> a
    extend :: (w a -> b) -> w a -> w b

注意“对称”。


另一件事是逆变函子,定义为:

import Data.Functor.Contravariant
class Contravariant f where
    contramap :: (b -> a) -> (f a -> f b)

【讨论】:

  • 函子 C -> D 不是函子 D -> C 的对偶吗?所以 a 函子的对偶并不是同一个函子本身,但“一般函子”的对偶概念仍然是“一般函子”。我想我只是在玩语义,但是“函子是自对偶的”中的语言听起来像是声称单个函子可以以某种方式用作它们自己的逆,或其他东西。
  • @Ben 这或多或少地脱离了正式定义:en.wikipedia.org/wiki/Equivalence_of_categories#Definition
【解决方案2】:

供参考,

class Functor w => Comonad w where
  extract :: w a -> a
  duplicate :: w a -> w (w a)
  extend :: (w a -> b) -> w a -> w b

instance Applicative m => Monad m where
  return :: a -> m a
  (>>=) :: m a -> (a -> m b) -> m b

join :: Monad m => m (m a) -> m a

请注意,给定extractextend,您可以生成fmapduplicate,给定return>>=,您可以生成fmappure<*>join。所以我们可以只关注pure+>>=extract+extend

我想你可能正在寻找类似的东西

class InverseFunctor f where
  unmap :: (f a -> f b) -> a -> b

由于Monad 类使“放入”变得容易,同时只允许一种假设的方法“取出”,而Comonad 做了一些与之相反的事情,因此您的请求最初听起来是明智的。但是,>>=extend 之间存在明显的不对称性,这将阻碍任何定义 unmap 的尝试。请特别注意>>= 的第一个参数的类型为m aextend 的第二个参数的类型为 w a——不是 a

【讨论】:

  • 我们可以定义一个取消映射:“unmap f = extract .f .return”并输入签名“unmap :: Monad f, Comonad f => (fa -> fb) -> a -> b"
【解决方案3】:

【讨论】:

    猜你喜欢
    • 2014-12-25
    • 1970-01-01
    • 1970-01-01
    • 2013-02-06
    • 1970-01-01
    • 2011-01-11
    • 2011-09-25
    • 2015-02-26
    • 1970-01-01
    相关资源
    最近更新 更多