Haskell 学习笔记三:Functors
Functors, Applicatives 和 Monads
这里估计是最劝退的地方了,我会尽量用简单的语言描述。网上的很多资源说得太复杂了,天知道劝退了多少人,我第一次看的时候完全看不懂他们在说什么。
Functors
问:什么是 Functors?
我的回答:Functor 说白了就是一种属性(准确来说叫 typeclass
,你把它想象成 Java 的 Interface
),Functor 里面包着另外一个数据。一个数据类型只要实现了这个属性就是 Functor
。
超级简单是不是?就像一个盒子,盒子里面是另外一个东西。这个盒子就是 Functor。
举个例子就好理解多了。Haskell 有内置一个数据类型叫 Maybe
(就是 Java 的 Optional
,Haskell 太先进了以至于大家都要抄),是这样的:
data Maybe a = Nothing | Just a
是不是真的和 Java 的 Optional
一模一样,要么没有(Nothing),要么有(Just a)。
一个 functor 必须实现以下的函数:
class Functor f where
fmap :: (a -> b) -> f a -> f b
class 在这里是 typeclass 的关键字,同样你把它想象成 interface。
fmap
是一个函数,参数是一个函数和一个 functor。fmap 会把 functor 里面的值喂给这个函数,返回的结果包在一个新的 functor 里。它和 <$>
是同义词(想象成 C 的 #define),一模一样。fmap a b
可以写成 a <$> b
。
想象一下,盒子里面有一个老婆。老婆被拿出来做成了老婆饼。老婆饼被装进了一个新的盒子并返回。
回到刚才那个 Maybe
的例子。Maybe
作为一个 Functor,就实现了这几个函数。具体的实现代码是这样的:
instance Functor Maybe where
fmap _ Nothing = Nothing
fmap f (Just a) = Just (f a)
超级简单是不是。不要被 instance Functor
吓到,其实就是 Java 的 implements Functor
。
上手试试吧:
Main> fmap (+1) (Just 0)
Just 1
在这里,盒子是(Just 0)。盒子里面装着老婆(0)。老婆(0)被做(+1)成了老婆饼(1)。老婆饼(1)被装进了盒子(Just 1)并且出货了。
你甚至还可以 fmap (+) (Just 1)
,这样出来的就是一个装着函数的盒子。仔细想想,它其实是符合类型签名的。
你肯定懂了。