代码之家  ›  专栏  ›  技术社区  ›  uhbif19

为什么Functor类没有返回函数?

  •  21
  • uhbif19  · 技术社区  · 11 年前

    从范畴的观点来看,函子是两个映射的对(一个在对象之间,另一个在类别的箭头之间),遵循一些公理。

    我假设,每个Functor实例都与数学定义类似,即可以映射对象和函数,但Haskell的 Functor 类只有函数 fmap 其映射函数。

    为什么?

    更新 换句话说:

    每个Monad类型 M 具有功能 return :: a -> M a .

    和Functor类型 F 没有功能 return :: a -> F a ,但仅限于 F x 构造函数。

    5 回复  |  直到 10 年前
        1
  •  16
  •   laughedelic    2 年前

    有两个级别:类型和值。由于Hask的对象是类型,因此只能使用类型构造函数映射它们 * -> * 种类:

    • α -> F α (用于 Functor F ),
    • β -> M β (用于 Monad M ).

    然后对于函子,你需要一个态射映射(即函数,是值):

    fmap :: (α -> β) -> (F α -> F β)
    

    重要的是 return :: α -> M α 属于 Monad 不是类型的映射器 α M α 正如你所想。根据monad的数学定义, return 对应于自然转换 从…起 Id 函数到 M 函子。以及 身份证件 函子在Hask中是隐式的。monad的标准定义还需要另一种自然转换 M ◦ M -> M 。所以翻译成Haskell看起来像

    class Functor m => Monad m where
        return :: Id α -> m α
        join :: m (m α) -> m α
    

    (附带说明:这两个自然变换实际上是单位和乘法,这使monad成为 内函子范畴中的幺半群 )

    实际定义不同,但相当。看见 Haskell/wiki 在这方面。

    如果采用从标准绑定派生的类复合运算符 >>= :: m α -> (α -> m β) -> m β :

    (>=>) :: Monad m => (α -> m β) -> (β -> m γ) -> (α -> m γ)
    f >=> g = \a => f a >>= g
    

    你可以看到,这实际上是关于 Kleisli category 。另请参见 article on nLab 关于计算机科学中的单子。

        2
  •  8
  •   Community CDub    7 年前

    类别的对象包括 与OO编程语言中的对象相同(我们更喜欢调用 价值观 在Haskell;讨论了它们在范畴理论中的含义 here ). 相反 哈斯克 类型 .哈斯克尔 Functor s是内函子 哈斯克 ,即通过以下方式将类型与类型关联:

    前奏曲>:k可能
    可能::*->*
    前奏曲>:k整数
    内部::*
    前奏曲>:k可能Int
    可能Int::*

    OTOH 箭头 属于 哈斯克 实际上是一些函数类型的值 a -> b 这些以以下方式关联:

    fmap :: ( Functor (f ::   t     ->     f t       {- type-level  -} ) )
                 =>         (a->b)  ->  fmap(a->b)   {- value-level -}
                         ≡  (a->b)  ->  (f a->f b)
    
        3
  •  6
  •   scravy    11 年前

    尽管您在问题中使用了那些花哨的分类术语,并且应该对现有的答案完全满意,但这里尝试了一个非常简单的解释:

    假设那里 是一种功能 return (或 pure unit ... )在Functor类型类中。

    现在尝试定义一些常见的Functor实例: [] (列表), Maybe , ((,) a) (带左侧组件的元组)

    够简单了,嗯?

    以下是普通的Functor实例:

    instance Functor [] where
       fmap f (x : xs) = f x : fmap xs
       fmap _ []       = []
    
    instance Functor Maybe where
       fmap f (Just x) = Just (f x)
       fmap _ Nothing  = Nothing
    
    instance Functor ((,) a) where
       fmap f (x, y) = (x, f y)
    

    那么...怎么样 回来 现在为Functor?

    列表:

    instance Functor [] where
       return x = [x]
    

    好吧也许呢?

    instance Functor Maybe where
       return x = Just x
    

    可以现在Tuples:

    instance Functor ((,) a) where
       return x = (??? , x)
    

    您知道,应该将哪个值填充到该元组的左侧组件中是未知的。实例声明表示它有一个类型 a 但我们不知道该类型的值。也许a型是 Unit 只有一个值的类型。但如果 Bool ,我们应该 True False ? 如果是的话 Either Int Bool 我们应该带吗 Left 0 Right False Left 1 ?

    所以你看,如果你有 回来 在Functors上,您通常无法定义许多有效的函子实例(您需要施加类似FunctorEmpty类型类的约束)。

    如果您查看文档 Functor Monad 你会发现 Functor ((,) a) 但不适用于 Monad ((,) a) 。这是因为你无法定义 回来 为了那件事。

        4
  •  4
  •   Tom Ellis    11 年前

    如果你有

    instance Functor F where
        fmap = ...
    

    然后类型构造函数 F 对象(即类型)上的操作是否采用类型 T 到类型 F T fmap 是态射(函数)上的作用取函数 f :: T -> U fmap f :: F T -> F U .

        5
  •  0
  •   Zim    2 年前

    在范畴论中,函子将所有对象从一个范畴映射到另一个范畴,但函子不映射 对象中的元素 .