仿函数的目的

时间:2017-05-01 09:23:43

标签: scala functional-programming monads functor

我试图了解仿函数并理解概念而不是它的目的?

请考虑以下示例:

val list1 = List(1,2,3)
val list2 = Functor[List].map(list1)(_ * 2)

有什么好处:

list1.map(x => x * 2)

4 个答案:

答案 0 :(得分:7)

目的不一定是Functor[List].map(list1)(_ * 2),而是:

def timesTwo[F[_]: Functor](f: F[Int]) = 
  Functor[F].map(f)(_ * 2)

抽象可以映射的所有内容的能力。

答案 1 :(得分:4)

仿函数是一个类型构造函数F[_]以及一个函数

def fmap[A,B](f: A => B): F[A] => F[B]

(这与cats中的编写方式不同,但实现相同且可互换)

那是什么意思? 类型构造函数基本上是类型之间的映射。为它提供类型A,它为您提供结果类型F[A]

您拥有fmap功能的事实意味着以下内容:每次您从F[A]转到{{F[B]时,您都可以从A转到B 1}}。

每个探子都必须遵守这些身份

  1. fmap(identity[A]) == identity[F[A]]
  2. fmap(a compose b) == fmap(a) compose fmap (b)
  3. 仿函数法则确保类型级函数(类型构造函数)和值级函数(A => BF[A] => F[B])能够很好地协同工作。

    有什么好处

    的好处是您可以使用不同的语法编写一些函数。事实上,在您的示例中,Functor[List].map(list1)(_ * 2)比简单地list1.map(_ * 2)更难写。

    好处是你可以编写适用于任何仿函数的函数。

    这是一个例子

    import cats.Functor
    
    def foo[A,B,F[_]: Functor](fb: F[B], ab: A => B)(eab: Either[F[A],F[B]]): F[B] = 
        eab.fold(fa => Functor[F].map(fa)(ab),identity)
    

答案 2 :(得分:1)

仿函数是一种类型类,它抽象出可以制作的所有类型的类似地图操作。通过这样做,我们可以统一的方式操作这些类型的实例。

答案 3 :(得分:0)

我认为查看仿函数地图函数的类型签名是有用的

map :: (a -> b) -> Functor a -> Functor b

这为我们提供了一种方法,可以将值放在容器(Functor)中,并使用普通函数(使用map)对该值进行操作,而无需将值从容器中取出。

然后可以将Functor视为高阶类型;也就是说,它是一个包含另一个值的值,但是具有与之交互的统一界面 - 这个界面为仿函数提供了一种独特的表达形式,使它们特别适合某些问题