Functors如何有用? [英] How are Functors useful?

查看:104
本文介绍了Functors如何有用?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我们知道使用 map 方法的任何泛型类型 F [_] ,这符合一些法律,是一个函数。例如, List [_] Option [_] F [A] = Env =>一个是函子。我只是想知道这个函子抽象是否有意义。

我如何使用他们是仿函数的事实?你能举出一个非平凡计算的例子,它会使用 map 并且实际上有用吗?

解决方案

像函数这样的概念最大的好处之一是有泛型构造,它们允许你从更简单的函子中构建更复杂的类型,并保证这些复杂类型有一定的性质。可以理解的是,当你把它们看作是孤立的时候,它们看起来毫无意义,但是当你学习和掌握的结构越多时,它们越变得越有用。

其中之一更简单的例子是组合函子的几种方法也产生函子;例如,如果 List [A] Option [A] 是仿函数,那么它们是:




  • 函子的组成:> 列表[Option [A]] Option [List [A]]

  • 函子的产品: ],选项[A])

  • 函子总数: [List [A] [A]]



我不知道在Scala中写出这些,但是在Haskell类似这些事实转化为泛型代码,如下面的例子:

pre $ - 一个泛型类型来表示任意两个函子的组合
- `f`和`g`。
newtype Compose f g a = Compose {getCompose :: f(g a)}

- 如果`f`和`g`是仿函数,`Compose f g`也是。
实例(Functor f,Functor g)=> Functor(Compose fg)其中
fmap f(Compose fga)= Compose(fmap(fmap f)fga)

这是一个非常简单的例子,但是:


  • 它作为一个分析工具已经很有用至少。人们在实践中编写的数据类型很多时,当你通过这个例子的镜头观察它们时,会发现它们是简单仿函数的产物,总和或组合。因此,一旦理解了这些构造,就可以在编写复合类型时自动感知它是一个函数,并且如何编写它的 map()操作。 >
  • 更复杂的示例具有相同的风格:


    • 我们有一个通用构造当使用实现 Functor ;

    • 的类型实例化时的合同当我们添加 Functor 执行到任何类型,我们可以在该构造中使用该类型。




一个更详细的例子是免费单子(链接有一个扩展的Scala例子),一个通用解释器结构依赖于用户提供的 Functor s来定义语言的说明。其他链接(并且这些链接大部分来自Google搜索):


We know that any generic type F[_] withmap method, which complies to some laws, is a functor. For instance, List[_], Option[_], and F[A] = Env => A are functors. I am just wondering if this functor abstraction is meaningful.

How can I use the fact that they are functors ? Could you show an example of non-trivial computation, which would use the map and be actually useful ?

解决方案

One of the biggest benefits of concepts like functions is that there are generic constructions that allow you to build more complex types out of simpler functors, and guarantee that these complex types have certain properties. Functors understandably seem rather pointless when you consider them in isolation as you have done, but they become more and more useful the more such constructions you learn and master.

One of the simpler examples is that several ways of combining functors also yield a functor; e.g., if List[A] and Option[A] are functors, so are:

  • Composition of functors: List[Option[A]] and Option[List[A]]
  • Products of functors: (List[A], Option[A])
  • Sums of functors: Either[List[A], Option[A]]

I don't know enough to write this out in Scala, but in Haskell facts like these translate into generic code like these examples:

-- A generic type to represent the composition of any two functors
-- `f` and `g`.
newtype Compose f g a = Compose { getCompose :: f (g a) }

-- If `f` and `g` are functors, so is `Compose f g`.
instance (Functor f, Functor g) => Functor (Compose f g) where
  fmap f (Compose fga) = Compose (fmap (fmap f) fga)

This is a very simple example, but:

  • It's already useful as an analytical tool at least. A lot of data types that people write in practice, when you look at them through the lens of this example, turn out to be products, sums or compositions of simpler functors. So once you understand these constructions you can automatically "sense" when you write a complex type that it is a functor, and how to write its map() operation.
  • The more elaborate examples have the same flavor:
    • We have a generic construction that guarantees certain contracts when instantiated with a type that implements Functor;
    • When we add a Functor implementation to any a type, we gain the ability to use that type in that construction.

A more elaborate example is free monads (link has an extended Scala example), a generic interpreter construction that relies on user-supplied Functors to define the "instructions" for the language. Other links (and these are mostly straight from a Google search):

这篇关于Functors如何有用?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆