【问题标题】:What means precisely "function inside a functor"究竟是什么意思“函子内的功能”
【发布时间】:2012-12-06 22:03:43
【问题描述】:

在范畴论中,函子是两个范畴之间的同态。在 Haskell 中,据说 applicative functor 允许我们在 “inside a functor” 中应用函数。是否可以将“函子内的函数”这句话翻译回数学或提供其他一些见解? (我知道函子可以是Maybe[] 等,但仍然很难理解这个概念。)

【问题讨论】:

  • 相关:How much is applicative really about applying, rather than “combining”?(我仍然没有真正找到我的问题的答案,但应用程序的数学性质被触及了很多)
  • @leftaroundabout 关于类似主题的优秀和更高级的问题。感谢您的链接。
  • 查看应用函子 (<*>) 的“the”关键组件的类型是否有帮助(Applicative f => f (a -> b) -> f a -> f b),或者您是否正在寻找比这更“深”的东西?

标签: haskell category-theory


【解决方案1】:

我的范畴论一点都不强(我是从 Haskell 的编程方面开始的,最近一直在尝试学习它的一些概念的范畴论基础)。但这是我所拥有的:

在 Haskell 中,函子是类型构造函数,这意味着它从一般类型映射到“函子中的类型”。

在范畴论中,函子从一个范畴的对象映射到另一范畴的对象。

在将类别理论应用于 Haskell 时,我们假设我们正在使用类别 Hask,即 Haskell 类型的类别。

所以 Haskell 函子不是一般范畴论的函子;它们都从 Hask 映射到 Hask 的子类别(因为某些函子 f 的类型 f a 和任意类型 a 仍然是 Haskell 类型)。例如,Maybe 函子将 Hask 中的对象(类型)映射到 Maybe a 形式的类型类别。

函数在 Haskell 中是一等的,所以函数类型是完全普通的类型(并且是 Hask 的对象),所以仿函数将函数类型映射到“函数类型在函子”。因此,短语“函子内的函数”是一种类型中 value 的简写,该类型是通过将函子应用于函数类型而产生的。例如Just (+1)Maybe (Int -> Int) 类型中的一个特定值,它是Maybe 函子将对象Int -> Int 映射到的对象(类型)。

因此,“应用函子”是具有一些额外规则的函子,这些规则足以获取 ,这些值是函子“目标”类别的对象类型中的函数,并应用那些值到目标类别中类型中的其他值。

再次以Maybe 为例,如果我们只知道它是一个函子,它为我们提供了对象Int -> CharMaybe (Int -> Char) 之间以及对象IntMaybe Int 之间以及对象之间的对应关系对象CharMaybe Char。但是虽然我们有能力在Int -> CharInt 中获取一个值并在Char 中产生一个值,但Maybe 作为一个函子并不能保证我们有能力进行一些相应的操作具有Maybe (Int -> Char) 中的值和Maybe Int 中的值。

当我们也知道它是一个应用函子时,我们确实有能力在Maybe (Int -> Char) 中获取一个值,在Maybe Int 中获取一个值并在Maybe Char 中生成一个值,这满足应用程序的某些属性将Int -> Char 值转换为Int 值。

据我所知,从纯范畴论的角度来看,应用函子并不是很有趣。这可能是因为范畴论关注的是 objects 之间的关系,这对应于 Haskell 中的类型,但从编程的角度来看,应用函子是由这些类型中的 之间的关系驱动的? (我们希望使用仿函数获得的“函数类型”中的值仍然能够应用于事物进行计算)。

【讨论】:

    【解决方案2】:

    翻译回数学

    在一个封闭的幺半群范畴中,有一个“指数”的概念,它“内化”了态射关系。然后,您可以评估这些指数。也就是说,你有一种说法(请原谅我的想法,Stackoverflow 缺少 mathjax)

    eval : (a ~> b,a) -> b
    

    以及用于柯里化和非柯里化的元操作。
    “应用函子”以“适用”方式映射指数,F (a ~> b) 可以与F a 组合得到F b。这是因为应用函子是单曲面函子,所以它们有一个操作(在目标类别中)

    f a -> f b -> f (a,b)
    

    当您还 fmap eval 时,它会从 Haskell 中为您提供 ap

    我怀疑这是否有用,

    Haskell

    了解应用函子的最佳方法是查看类型

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

    简单的例子是

    newtype Id a = Id a
    instance Applicative Id where
      pure a = Id a
      Id f <*> Id a = Id (f $ a)
    

    Id 也是一个Monad。事实上,所有Monads 都是Applicative

    pure = return
    mf <*> mx = do f <- mf
                   x <- mx
                   return (f x)
    

    一个更有趣的例子是无限序列

    data Seq a = Seq a (Seq a)
    instance Applicative Seq where
      pure a = Seq a (pure a)
      (Seq f fs) <*> (Seq x xs) = Seq (f x) (fs <$> xs)
    

    您可以认为这相当于列表中的zipWith $。所有Monads 都是Applicative,但我认为无限序列很有趣,因为相应的 monad 实例......不明显(而且相当慢)。它将作为练习留给读者(顺便说一句,我正在从我记得读过的东西中锻炼这个例子/练习,我认为 pigworker 写在这个网站上)。

    【讨论】:

    • Applicative的定义中,不应该有&lt;*&gt;而不是&lt;$&gt;吗?
    • 我知道我要迟到了,但 eval : (a ~&gt; b,a) -&gt; a 不应该是 eval : (a ~&gt; b,a) -&gt; b 吗?
    • @raichoo 确实如此。固定。
    猜你喜欢
    • 1970-01-01
    • 2011-03-12
    • 2014-10-29
    • 2016-01-27
    • 2014-12-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多