为什么Haskell中没有`Cofunctor`类型类?

时间:2016-01-11 22:48:47

标签: haskell monads functor

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

3 个答案:

答案 0 :(得分:21)

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相同,因此使用Functor定义monad和comonad。但是,不要让它让你认为monad和comonad是同一个东西,他们不是。

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)

答案 1 :(得分:5)

实际上,你错了:有一个!

https://hackage.haskell.org/package/acme-cofunctor

答案 2 :(得分:4)

供参考,

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 {1}},<*>joinpure。因此,我们只关注>>= + extractextend + class InverseFunctor f where unmap :: (f a -> f b) -> a -> b

我想你可能正在寻找像

这样的东西
Monad

由于Comonad类使得“放入内容”变得容易,而只允许某种假设性方法来“解决问题”,并且>>=做了与此相反的事情,因此您的请求最初听起来很明智。但是,extendunmap之间存在显着的不对称性,这会阻碍任何定义>>=的尝试。请特别注意m a的第一个参数的类型为extendw a的第二个参数类型为a - 不是 GET

相关问题