haskell:函数作为 functor、applicative、monad 和 monoid

在 haskell 里,function 本身也是 functor、applicative、monad 和 monoid。

理念

function 是天然的 container。

- b 是 test 函数包含的 value, test a 函数调用是获取 container 内部 value 的方式

test :: a -> b

function as functor

将 fmap 应用于 function 这种 functor,fmap f function。相当于构造一个新函数 \a -> f (test a)

test a 把 function 里包含的 value 取出来,作为 f 的参数传入。然后 fmap 需要返回 functor,所以返回包裹的新函数 \a -> f (test a)

验证代码如下

- 输出 (2 + 1) * 2 = 6 

fmap (\x -> x * 2) (\x -> x + 1) $ 2

function as applicative

applicative 的函数 <*> 签名是 (<*>) :: Applicative f => f (a -> b) -> f a -> f b,两个 container 里,一个包含的 value 是 function 类型,另一个包含的是参数,<*> 把两个容器合并起来,将另一个 container 里的参数 value,传入 function 类型的 container 里。

function 自身是容器,其返回值是容器内的 value。那么容器里的 value 又是函数的情况就是高阶函数(返回函数的函数)。

验证代码如下

- 两个函数的第一个参数是同样的,其返回值,一个是函数,一个是参数,调用后 z * 3 的结果,作为参数,传入 y -> x + y 函数

- 相当于构造了函数 \x -> x + (x * 3),输出 12

(\x y -> x + y) <*> (\z -> z * 3) $ 3

function as monad

monad 的 >>= 函数签名是 (>>=) :: Monad m => m a -> (a -> m b) -> m b,第二个参数是一个用上一个容器里的 value 构造下一个容器的函数。

验证代码如下

- 第一个 monad 里的 value 是 x + 1,作为参数传入了 `a -> m b`

- 因为 `a -> m b` 也要返回相同的 monad,所以它是高阶函数,上一个 monad 的 value 填充了其第一个参数,第二个参数跟上一个 monad 的参数是相同的。

- 相当于构造了函数 \x -> (x + 1) * x,输出 6

(\x -> x + 1) >>= (\x y -> x * y) $ 2

function as monoid

function 可以满足 monoid 的两个构建 memptymappend,其中 memptyid 函数,任何函数跟 id 函数组合起来,等于其自身。mappend则是 compose,组合两个函数,通常用 . 函数来表示。

f.id = f

id.f = id

(f.g).h = f.(g.h)

use do notation for function

既然 function 也是 monad,那么我们就可以使用 do notation 来写。

- 从 n1 是 \x -> x + 1 的返回值

- 我们用 const 构造一个函数 monad,方便 <- 获取值

- 最后用 const 构造新的函数 monad,结束这个过程

- test 2 将输入 (x + 1) + ((x + 1) *2) = 9

test = do

n1 <- \x -> x + 1

n2 <- const $ n1 * 2

const $ n1 + n2

以上是 haskell:函数作为 functor、applicative、monad 和 monoid 的全部内容, 来源链接: utcz.com/z/264573.html

回到顶部