您的位置:首页 > 其它

Functor与fmap

2015-11-06 11:41 169 查看
一.

Functor俗称仿函数或者函子,他是一个类型类,我们先看看他的结构

scala> :kind Functor
scalaz.Functor's kind is X[F[A]]


可以看出它是一个类型构造器的构造器,但是不像List等序列(强调的是容器),我们这里X并不是像F容器,我们可以把X看作action集合,所以我猜他才被称呼为Functor的

Functor里最重要的部分就是map的函数了

/** Lift `f` into `F` and apply to `F[A]`. */
def map[A, B](fa: F[A])(f: A => B): F[B]


我们必须理解Functor中的map是做了什么事情,而且必须熟悉,不然后面更加抽象的就无法理解了(当然即使你理解这个后,后面的不一定能理解,后面会更加抽象!)

我们先看看我们以前熟悉的map

scala> List(1,2,3) map { _ + 1}
res5: List[Int] = List(2, 3, 4)


或许你认为该map与上面的一样,当然意义是一样的,但是结果是不一样的,这里我们的map返回的依旧是原本的序列

而上面的并不是返回一个Functor,他返回的只是当初的一个容器类,也即是F[_](所以他才叫做函子)

具备函数的特性:
scala> def a:Int=>Int = a => a + 1
a: Int => Int

scala> :kind a
scala.Function1's kind is F[-A1,+A2]

scala> :kind a(1)
scala.Int's kind is A

scala>


好了,上面我们是通过字面意识来理解Functor的,下面我们以Functor的真正意义来理解吧

1.Functor是个lift过程

什么样的lift呢?

我们举个例子:

(1).我们有n个元素

val a = 1,2,3,4(我们只是打比方,实际没有这个语法)

如果我们要对a执行一个加一操作,那么我们必须编写一个函数,如

def fun:Int => Int = _ + 1

这样是符合的,因为a就是int类型!

(2).如果a是个序列呢?

val a = List(1,2,3)

必然是

def fun:List[Int] => List[Int]

我们从一个裸体的Int到包装的List型的fn,这是个lift过程,这就是functor的工作了

2.对1部分的总结

lift就是把函数的映射"映射"到另一个映射中



从而我们才可以对F[_]的类型的数据进行操作

3.使用

上面我已经解析的够清楚了,至少个人觉得比我看的资料没那么抽象了

估计有人说,以上的操作不是直接使用

List(1,2,3,4) map {_ + 1}就可以完成了吗?如果你这么觉得的话就得好好看monad了

scala> (1, 2, 3) map {_ + 1}
res7: (Int, Int, Int) = (1,2,4)


这里我在废话讲解一下吧,不然如果你还是不懂那么就无法下去了

首先map接受一个Int => Int的函数,然而(1,2,3)并不是int

所以(1,2,3)通过隐式的Functor将Int => Int 提升(Int, Int, Int) => (Int, Int, Int)

从而才能计算

二.

上面把基本的讲解了,而Functor的操作似乎可以直接通过F[_]的成员函数操作,而不必通过X的lift过程.好像是这样吧,下面我们就进入另一个------------------------

操作对象是函数,当然核心lift还是不变的

scala> (((x: Int) => x + 1) map {_ * 7})
res8: Int => Int = <function1>

scala> res8(12)
res9: Int = 91

scala> res8(1)
res10: Int = 14


这回你知道Functor的意义了吧,他不仅通过lift对元素或者容器进行操作,他甚至可以对函数进行操作

他把

Int => Int

提升为

func => func

三.

与fmap的区别,顺序的区别

但是两个都是lift的使用(原理一样)

看看签名

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


而我们的map是

F.map(a->b)

翻译成

(F a) -> (F b)

从Functor角度看只是实现的方式不同,原理一样.再次强调

----都是lift的使用

然后

看看Functor的其他操作

scala> List(1, 2, 3) >| "x"
res47: List[String] = List(x, x, x)

scala> List(1, 2, 3) as "x"
res48: List[String] = List(x, x, x)

scala> List(1, 2, 3).fpair
res49: List[(Int, Int)] = List((1,1), (2,2), (3,3))

scala> List(1, 2, 3).strengthL("x")
res50: List[(String, Int)] = List((x,1), (x,2), (x,3))

scala> List(1, 2, 3).strengthR("x")
res51: List[(Int, String)] = List((1,x), (2,x), (3,x))

scala> List(1, 2, 3).void
res52: List[Unit] = List((), (), ())


四.

应用式,如果你理解了上面的内容了,那么就看这篇介绍应用式(自已就懒得敲了)

http://eed3si9n.com/learning-scalaz/Applicative.html
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: