标签: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