【问题标题】:What are the exact applications of Functor, PointedFunctor, ApplicativeFunctor and Monad? [closed]Functor、PointedFunctor、ApplicativeFunctor 和 Monad 的具体应用是什么? [关闭]
【发布时间】:2012-09-29 15:14:38
【问题描述】:

我研究 Scala(以及扩展的 Haskell)已经有一段时间了,我完全被他们的类型系统和函数范式所吸引。就在最近,我偶然发现了“类型级编程”,并被卷入了诸如 Functor 之类的东西和其他我没听说过的东西(除了 Monad,我知道它是一种神秘的东西,但不知道要使用什么它!)。 我研究了 Haskell 中的概念(顺便被它的类型系统和类型推断能力迷住了),我对类型成为 Functor、PointedFunctor、ApplicativeFunctor 或 Monoid 的含义有了一个纯技术层面的深刻理解(即使在技术层面上,我仍然不知道 Monad 是什么)但我觉得自己像个白痴,因为我认为这一切没有用,除了可能获得了对某些概念的良好分类(?)。这些东西有什么用?为什么要让生活如此复杂?为什么要研究这些东西并将它们分类为不同的类别?

【问题讨论】:

  • 吹毛求疵:我不会说这些简单的类型类有资格作为类型级编程(而且我从未见过它们被这样分类),尽管它们显然使用类型。类型级编程在类型方面做得更多。
  • @delnan Tnx 进行澄清。非常正确。正如问题中提到的,我在学习类型级编程时被拖到了他们身边。并不是说它们本身就是类型级编程。
  • 投票支持重新开放:这个问题可能很笼统,但我认为这是一个常见的问题,我们已经得到了一些好的、“建设性”的答案。并非所有“开放式”问题都是不好的或容易引发激烈的争吵,它们通常可以通过从不同角度阐明一个主题来产生有趣的见解。
  • @Landei 我很久以前就放弃了 ;-)

标签: scala haskell types monads functor


【解决方案1】:

另外我想指出单子不是“神秘的”。尤其是类似容器的 monad(list、Maybe、Identity)非常容易理解。它们类似于函子,但有一个转折:使用fmap 保留原始函子的“形状”(例如列表中的元素数),例如你不能使用fmap 来实现类似filter 的东西。这就是为什么 monad 有一个名为“bind”的函数(在 Haskell 中是 (>>=)),它允许这种事情,但它们也不是魔法(例如,对于列表,它与旧的 concatMap 相同)。此外,monad 有一个函数 return 来包装单个值。

现在很多其他的,不是“容器式”的东西都是单子。有些 monad 可以对“存储的计算”进行操作(Cont 表示延续 monad)。他们可以提供(Reader)、收集(Writer)或持有(State)某种“附加上下文”。一个非常有用的“上下文”是“世界其他地方的状态”,更广为人知的是IO。在这种情况下,类型系统(尤其是多态性和类型类所施加的限制)可以屏蔽不需要的交互,并强制一定的计算顺序(这在惰性语言中不是微不足道的),所以我们不需要肮脏的 hack 或语言 back-门,以便用纯语言做 IO。有些人认为这是一种魔法,但它只是巧妙地使用了类型系统,而 monad 并不是解决这个问题的唯一方法(例如,Clean 语言为此使用了“唯一性类型”)。

【讨论】:

    【解决方案2】:

    我们首先应该问:什么是函子、单子……。除非我们知道这些概念是什么(意思),否则很难谈论它们的用途。

    这些概念来自category theory。 它们源于这样一个事实,即数学中的许多对象(以及因此在函数式编程中)共享一些共同的抽象属性。一旦我们了解并理解了这些属性,我们就可以使用它们来编写非常通用的代码,这些代码可重用于大量任务。


    举个例子:功能大家都知道

    map :: (a -> b) -> ([a] -> [b])
    

    拥有从ab 的函数,我们可以创建一个适用于列表[a] 的函数。 Functors 是这个概念的概括。任何可以以这种方式映射(并保留functor laws)的东西都称为函子。所以Functor 声明

    fmap :: Functor f => (a -> b) -> (f a -> f b)
    

    在列表的情况下,f 变为 []。使用fmap,我们可以映射列表(它等于map),也可以映射Maybes、各种集合、树,甚至函数。

    另见

    【讨论】:

      【解决方案3】:

      “这些东西有什么用?” 啊!你可以用它们来写 FizzBu​​zz: http://dave.fayr.am/posts/2012-10-4-finding-fizzbuzz.html

      【讨论】:

        【解决方案4】:

        为什么要让生活如此复杂?

        他们都是为了让生活更简单

        首先,它们使我们编写的代码更加简洁明了。

        其次,它们增加了我们的表达能力,而无需添加真正的新语言功能。 例如,Monads 让您使用标准语法来表达复杂的计算上下文,Functors 让您以标准方式思考和编程数据结构,Applicative Functors 让您可以像处理直接数据一样简单地处理有效或复杂的计算上下文,让您在纯数据之外干净地使用函数范式。

        它们都有助于代码重用并帮助我们理解彼此的代码,因为它们为我们提供了一种思考事物的标准方式。

        一旦你习惯了它们,你就不想没有它们了!

        【讨论】:

          【解决方案5】:

          它们都是抽象的。例如。幺半群是支持零元素和加法的东西(必须是关联的)。例如整数、列表、字符串等。我认为为所有这些不同类型提供一个通用“接口”相当不错。

          那么它们为什么有用呢?例如,您可以为所有幺半群编写通用 sum 函数。您只需编写一个通用函数,而不是为字符串、整数等编写一个。我认为这很有用。

          【讨论】:

            猜你喜欢
            • 2017-12-28
            • 2012-01-29
            • 1970-01-01
            • 2020-01-31
            • 2012-01-17
            • 1970-01-01
            • 2012-11-12
            • 1970-01-01
            • 2011-11-18
            相关资源
            最近更新 更多