Haskell学习-functor (2)

IO ,下面的IO的实例,可以把 getLine 看做是一个去真实世界中拿取字串的盒子, 而 applicative functor 表达式会创造一个比较大的盒子,这个大盒子会派两个盒子去终端拿取字串,并把结果串接起来放进自己的盒子中。

--IO 的 Applicative instance instance Applicative IO where pure = return a <*> b = do f <- a x <- b return (f x) -- 实例 将输入的两个字符串合并 (++) <$> getLine <*> getLine aa bb > "aabb"

Applicative Functor 的 (->) r 形态

(->) r 形态定义

instance Applicative ((->) r) where pure x = (\_ -> x) f <*> g = \x -> f x (g x)

用 pure 将一个值包成 applicative functor 的时候,他产生的结果永远都会是那个值

将两个 applicative functor 喂给 <*> 可以产生一个新的 applicative functor

接着综合使用上面的知识,来看一下实际应用applicative的几种方式。相比起functor,applicative functor要更强大和灵活。

-- 左结合形式, 第一项必须为含有函数的functor,右边全部为functor pure (\x y z -> x+ y +z) <*> Just 3 <*> Just 4 <*> Just 5 > Just 12 [(+3),(*2)] <*> [1,2] > [4,5,2,4] -- fmap(<$>) 形式,第一项为普通函数,右边都为functor (+) <$> Just 1 <*> Just 2 > Just 3 (\x y z -> x + y +z) <$> [1,2] <*> [2,3] <*> [4,5] > [7,8,8,9,8,9,9,10] -- (<$>) (->) r 形式,全部为普通函数,用单个参数调用执行 (\x y z -> [x,y,z]) <$> (3+) <*> (*100) <*> (`div`2) $ 2 > [5,200,1] Applicative Functor 辅助函数

liftA2
只是applicative的套用函数而已,当然还有3个参数的版本 liftA3,而 liftA 则等价于 fmap

-- 与applicative 的等价形式 liftA2 f a b = f <$> a <*> b -- 以下表达式功能一致 liftA2 (:) (Just 3) (Just [4]) (:) <$> Just 3 <*> Just [4] pure (:) <*> Just 3 <*> Just [4] > Just [3,4]

sequenceA
  当套用在函数上时,sequenceA 接受装有一堆函数的list,并回传一个回传list的函数。当我们有一串函数,想要将相同输入都喂给它们并查看结果的时候,sequenceA非常好用。
  当使用在 I/O action 上的时候,sequenceAsequence 是等价的。他接受一串 I/O action 并回传一个 I/O action,这个 I/O action 会计算 list 中的每一个 I/O action,并把结果放在一个 list 中

-- 以下是两种实现sequenceA功能一致的函数 sequenceA (x:xs) = (:) <$> x <*> sequenceA xs sequenceA = foldr (liftA2 (:)) (pure []) sequenceA [Just 3, Just 2, Just 1] > Just [3,2,1] -- 将list组合成所有可能的组合 sequenceA [[1,2,3],[4,5,6]] > [[1,4],[1,5],[1,6],[2,4],[2,5],[2,6],[3,4],[3,5],[3,6]] sequenceA [(>4),(<10),odd] 7 map (\f -> f 7) [(>4),(<10),odd] > [True,True,True] -- and接受一串Bool,并在所有值都为True时才返回True and $ sequenceA [(>4),(<10),odd] 7 and $ map (\f -> f 7) [(>4),(<10),odd] > True

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wssyfg.html