标签:pre 函数返回 推出 param 变量 class func table 数字类型
整理一下 《Learn You a Haskell for Great Good !》 介绍的 Funtor
,Applicative Funtor
和 Monad
。
并不打算写 Monad
相关的教程 ╮(╯▽╰)╭
##柯里化
柯里化(Currying)是将多个参数的函数化成一系列单个参数函数组合的技术。
多参函数柯里化后传递和使用都更加灵活。
很多语言支持手动柯里化。这个过程很简单。比如在 JavaScript 中
1 |
|
在 Haskell 中多参函数接受参数不全时,会自动柯里化,返回一个接受剩余参数的函数。这个过程称为偏应用(Partial Apply,部分应用)
1 | Prelude> (+1) 2 |
两个函数的类型是这样的
1 | Prelude> :t (+1) |
类型签名,或者说类型声明,用于声明函数的类型,如参数的类型,接受几个参数,返回类型等。
上面 (+1)
函数的类型是
1 | Prelude> :t (+1) |
从左往右看,(+1)
说的是函数名。 ::
类型说明操作符。可读为 「……的类型是」
Num a
是一种类型约束。这部分很像变量声明,Num
指的是数字类型。 a
是变量名,可以任意取,习惯上为了方便使用单个字母。所以 Num a
的意思是 a
的类型为 Num
。
=>
表示推出。用于分隔类型约束和函数签名的主体。
a
表示接受一个变量 a
型的参数
->
表示返回
a
因为是在函数最后,所以就是返回一个 a
类型的参数。
Functor
是可以应用 fmap
的类型。
fmap
的类型是
1 | Prelude> :t fmap |
这里的签名有括号。不影响结果。可以简单的认为把 (a -> b)
视为接受 a
返回 b
的函数。
从签名中可以看出,fmap
接受一个函数 a -> b
,再接受一个 Funtor f
类型的参数 a ,返回一个 Funtor f
类型的 b
把签名改一下,改成fmap :: Functor f => (a -> b) -> (f a -> f b)
这样理解为接受一个函数返回另外一个参数和返回值都是 Funtor f
类型的函数
看具体的例子。比如 Maybe
是一个 Funtor
。
1 | instance Functor Maybe where |
应用
1 | Prelude> fmap (+1) (Just 3) |
并不是实现了 fmap
的实例都能称为 Funtor
。要想成为 Funtor
必须满足 Functor Law (函子律)。
1 | fmap id = id |
第一条中 id
是一个返回自身的函数。也就是 x -> x
。fmap id = id
实际上是 point-free 写法,也就是无参写法。
写得完整一点是 fmap id x = id x
。意思是 fmap
应用返回自身的函数相当于直接应用返回自身的函数。
1 | Prelude> fmap id (Just 3) |
第二条说的是分配律。也就是应用两个函数的组合等用于分别应用两个函数结果的组合。
写的完整一点是 fmap f . g x = fmap f (fmap g x)
1 | Prelude> fmap ( (+1) . (*2) ) (Just 3) |
Applicative Functor
是可以应用 pure
和 apply (<*>
) 的 Funtor
1 | class (Functor f) => Applicative f where |
pure
的类型是 a -> f a
,用于将类型 a
转化为 Funtor f
类型的函数。
<*>
的类型是 f (a -> b) -> f a -> f b
,用于取出 Funtor f
类型中函数 a -> b
,再接受一个 Funtor f
类型的参数 a ,返回一个 Funtor f
类型 b 。
Maybe
是一个 Applicative Funtor
1 | instance Applicative Maybe where |
应用
1 | Prelude> pure Nothing |
同样并不是实现了 pure
和 <*>
的类型就是 Applicative Funtor
。
要想成为 Applicative funtor
必须满足 Applicative Functor Law 。
1 | pure f <*> x = fmap f x |
在第一条 pure f <*> x = fmap f x
可以得到其他几条
对于 Maybe
来说是这样的
1 | Prelude> pure (+1) <*> Just 3 |
Monad
是可以应用 bind (>>=
)的 Applicative Funtor
1 | class Monad m where |
这里的 return
相当于 Applicative Funtor
的 pure
。
不出所料的 Maybe
也是一个 Monad
1 | instance Monad Maybe where |
应用
1 | Prelude> return 1 :: Maybe Int |
同样并不是实现了 >>=
就是 Monad
。要想成为 Monad
必须满足 Monad Law (单子律)
1 | return x >>= f = f x |
对于 Maybe
来说是这样的
1 | Prelude> return 3 >>= (x -> return (x+1)) ::Maybe Int |
还有 Comonad
我懒得来写了(逃
Haskell 中的 Functor Applicative Functor 和 Monad · 拖鞋党的拖鞋摊
标签:pre 函数返回 推出 param 变量 class func table 数字类型
原文地址:https://www.cnblogs.com/wangziqiang123/p/11696355.html