Haskell语言学习笔记(58)Bifoldable
Bifoldable
class Bifoldable p where
bifold :: Monoid m => p m m -> m
bifold = bifoldMap id id
bifoldMap :: Monoid m => (a -> m) -> (b -> m) -> p a b -> m
bifoldMap f g = bifoldr (mappend . f) (mappend . g) mempty
bifoldr :: (a -> c -> c) -> (b -> c -> c) -> c -> p a b -> c
bifoldr f g z t = appEndo (bifoldMap (Endo #. f) (Endo #. g) t) z
bifoldl :: (c -> a -> c) -> (c -> b -> c) -> c -> p a b -> c
bifoldl f g z t = appEndo (getDual (bifoldMap (Dual . Endo . flip f) (Dual . Endo . flip g) t)) z
Bifoldable 是个类型类。主要用于折叠二元数据结构。
Bifoldable 的法则
bifold ≡ bifoldMap id id
bifoldMap f g ≡ bifoldr (mappend . f) (mappend . g) mempty
bifoldr f g z t ≡ appEndo (bifoldMap (Endo . f) (Endo . g) t) z
Either 是个 Bifoldable
instance Bifoldable Either where
bifoldMap f _ (Left a) = f a
bifoldMap _ g (Right b) = g b
(,) 是个 Bifoldable
instance Bifoldable (,) where
bifoldMap f g ~(a, b) = f a `mappend` g b
Const 是个 Bifoldable
instance Bifoldable Const where
bifoldMap f _ (Const a) = f a
应用 Bifoldable
Prelude Data.Bifoldable> bifoldr (^) (-) 2 (Left 2)
4
Prelude Data.Bifoldable> bifoldr (^) (-) 2 (Right 3)
1
Prelude Data.Bifoldable> bifoldr (^) (-) 2 (2,3)
2
Prelude Data.Bifoldable Control.Applicative> bifoldr (^) (-) 2 (Const 2)
4
Prelude Data.Bifoldable> bifoldl (^) (-) 4 (Left 2)
16
Prelude Data.Bifoldable> bifoldl (^) (-) 4 (Right 3)
1
Prelude Data.Bifoldable> bifoldl (^) (-) 4 (2,3)
13
Prelude Data.Bifoldable Control.Applicative> bifoldl (^) (-) 4 (Const 2)
16
手动计算
bifoldr (^) (-) 1 (2,3)
= appEndo (bifoldMap (Endo #. (^)) (Endo #. (-)) (2,3)) 1
= appEndo ((Endo #. (^) $ 2) (Endo #. (-) $ 3)) 1
= appEndo ((Endo (2^)) `mappend` (Endo (3-))) $ 1
= (2^) . (3-) $ 1
= 2 ^ (3 - 1) = 4
bifoldl (^) (-) 4 (2,3)
= appEndo (getDual (bifoldMap (Dual . Endo . flip (^)) (Dual . Endo . flip (-)) (2,3))) 4
= appEndo (getDual ((Dual . Endo . flip (^) $ 2) `mappend` (Dual . Endo . flip (-) $ 3))) 4
= appEndo (getDual ((Dual $ Endo (^2)) `mappend` (Dual $ Endo (subtract 3)))) 4
= (subtract 3) . (^2) $ 4
= (4 ^ 2) - 3 = 13
Bifoldable 其他函数
bifoldrM :: (Bifoldable t, Monad m) => (a -> c -> m c) -> (b -> c -> m c) -> c -> t a b -> m c
bifoldrM f g z0 xs = bifoldl f' g' return xs z0 where
f' k x z = f x z >>= k
g' k x z = g x z >>= k
bifoldlM :: (Bifoldable t, Monad m) => (a -> b -> m a) -> (a -> c -> m a) -> a -> t b c -> m a
bifoldlM f g z0 xs = bifoldr f' g' return xs z0 where
f' x k z = f z x >>= k
g' x k z = g z x >>= k
bitraverse_ :: (Bifoldable t, Applicative f) => (a -> f c) -> (b -> f d) -> t a b -> f ()
bitraverse_ f g = bifoldr ((*>) . f) ((*>) . g) (pure ())
bimapM_:: (Bifoldable t, Monad m) => (a -> m c) -> (b -> m d) -> t a b -> m ()
bimapM_ f g = bifoldr ((>>) . f) ((>>) . g) (return ())
biforM_ :: (Bifoldable t, Monad m) => t a b -> (a -> m c) -> (b -> m d) -> m ()
biforM_ t f g = bimapM_ f g t
bisequenceA_ :: (Bifoldable t, Applicative f) => t (f a) (f b) -> f ()
bisequenceA_ = bifoldr (*>) (*>) (pure ())
bisequence_ :: (Bifoldable t, Monad m) => t (m a) (m b) -> m ()
bisequence_ = bifoldr (>>) (>>) (return ())
biList :: Bifoldable t => t a a -> [a]
biList = bifoldr (:) (:) []
biconcat :: Bifoldable t => t [a] [a] -> [a]
biconcat = bifold
biconcatMap :: Bifoldable t => (a -> [c]) -> (b -> [c]) -> t a b -> [c]
biconcatMap = bifoldMap
biany :: Bifoldable t => (a -> Bool) -> (b -> Bool) -> t a b -> Bool
biany p q = getAny . bifoldMap (Any . p) (Any . q)
biall :: Bifoldable t => (a -> Bool) -> (b -> Bool) -> t a b -> Bool
biall p q = getAll . bifoldMap (All . p) (All . q)
Prelude Data.Bifoldable> bifoldrM (\x y -> [x+y]) (\x y -> [x*y]) 4 (2,3)
[14]
Prelude Data.Bifoldable> bifoldrM (\x y -> [x+y, x+y+1]) (\x y -> [x*y, x*y*2]) 4 (2,3)
[14,15,26,27]
Prelude Data.Bifoldable> bifoldlM (\x y -> [x+y]) (\x y -> [x*y]) 4 (2,3)
[18]
Prelude Data.Bifoldable> bifoldlM (\x y -> [x+y, x+y+1]) (\x y -> [x*y, x*y*2]) 4 (2,3)
[18,36,21,42]
Prelude Data.Bifoldable> bitraverse_ print print ("hello", "world")
"hello"
"world"
Prelude Data.Bifoldable> bimapM_ print print ("hello", "world")
"hello"
"world"
Prelude Data.Bifoldable> biforM_ ("hello", "world") print print
"hello"
"world"
Prelude Data.Bifoldable> bisequenceA_ (print "hello", print "world")
"hello"
"world"
Prelude Data.Bifoldable> bisequence_ (print "hello", print "world")
"hello"
"world"
Prelude Data.Bifoldable> biList ("hello","world")
["hello","world"]
Prelude Data.Bifoldable> biconcat (["hello"],["world"])
["hello","world"]
Prelude Data.Bifoldable> biconcatMap (++",")(++"!") ("hello","world")
"hello,world!"
Prelude Data.Bifoldable> biany ('e' `elem`)('e' `elem`) ("hello","world")
True
Prelude Data.Bifoldable> biall ('e' `elem`)('e' `elem`) ("hello","world")
False
Haskell语言学习笔记(58)Bifoldable的更多相关文章
- Haskell语言学习笔记(88)语言扩展(1)
ExistentialQuantification {-# LANGUAGE ExistentialQuantification #-} 存在类型专用的语言扩展 Haskell语言学习笔记(73)Ex ...
- Haskell语言学习笔记(79)lambda演算
lambda演算 根据维基百科,lambda演算(英语:lambda calculus,λ-calculus)是一套从数学逻辑中发展,以变量绑定和替换的规则,来研究函数如何抽象化定义.函数如何被应用以 ...
- Haskell语言学习笔记(69)Yesod
Yesod Yesod 是一个使用 Haskell 语言的 Web 框架. 安装 Yesod 首先更新 Haskell Platform 到最新版 (Yesod 依赖的库非常多,版本不一致的话很容易安 ...
- Haskell语言学习笔记(20)IORef, STRef
IORef 一个在IO monad中使用变量的类型. 函数 参数 功能 newIORef 值 新建带初值的引用 readIORef 引用 读取引用的值 writeIORef 引用和值 设置引用的值 m ...
- Haskell语言学习笔记(39)Category
Category class Category cat where id :: cat a a (.) :: cat b c -> cat a b -> cat a c instance ...
- Haskell语言学习笔记(72)Free Monad
安装 free 包 $ cabal install free Installed free-5.0.2 Free Monad data Free f a = Pure a | Free (f (Fre ...
- Haskell语言学习笔记(44)Lens(2)
自定义 Lens 和 Isos -- Some of the examples in this chapter require a few GHC extensions: -- TemplateHas ...
- Haskell语言学习笔记(38)Lens(1)
Lens Lens是一个接近语言级别的库,使用它可以方便的读取,设置,修改一个大的数据结构中某一部分的值. view, over, set Prelude> :m +Control.Lens P ...
- Haskell语言学习笔记(92)HXT
HXT The Haskell XML Toolbox (hxt) 是一个解析 XML 的库. $ cabal install hxt Installed hxt-9.3.1.16 Prelude&g ...
随机推荐
- FormData 知识点
通过FormData对象可以组装一组用 XMLHttpRequest发送请求的键/值对.它可以更灵活方便的发送表单数据,因此可以独立于表单使用. 如果你把表单的编码类型设置为multipart/for ...
- Angular 4 父组件调用子组件中的方法
1. 创建工程 ng new demo3 2. 创建子组件 ng g component child 3. 在子组件中定义方法greeting 4. 父组件html(第三行是模板中调用子组件的方法) ...
- Eclipse更改皮肤
今天在网上看到别人的Eclipse皮肤很漂亮,所以也就查了一下如何更改. 其实很简单,现在一起来: Help -> Install New Software -> add -> n ...
- js正则表达式30分钟入门教程
2011-10-27 13:23:15 如何使用本教程 最重要的是——请给我30分钟,如果你没有使用正则表达式的经验,请不要试图在30秒内入门——除非你是超人 :) 别被下面那些复杂的表达式吓倒,只要 ...
- JQuery返回Json日期格式的問題
用JQuery Ajax返回一個Entity的Json數據時,如果Entity的屬性中有日期格式,那返回來的是一串字符串,如下圖所示: 在網上找了很久也沒有找到一個好的解決方案,最後自己寫一個java ...
- PHP中文件类型 文件属性 路径以及 文件相关的函数
一: 文件类型判断: 1.is_dir() 判断是不是目录 2.is_file() 判断是不是文件 3.is_executable() 判断是不是可执行文件 4.is_readable() 判断是 ...
- java日期格式转换工具类
原文地址:http://blog.csdn.net/zhiweianran/article/details/7991531 package com.ace.backoffice.utils; impo ...
- Jmeter 问题集
1.配置分布式,调度机(master) 看不到 执行机(slave). 原因: slave是放在一个交换机下面,然后在这个交换机下面又接了个路由器,control连的这个路由器 解决: CONTROL ...
- 网络对抗 Exp0 Kali安装 Week1
2018-2019 网络对抗 Exp0 Kali安装 Week1 目录 一.下载 二.安装运行 三.配置 四.问题 一.下载 在百度中搜索kali linux 选择并点击Kali Linux | Pe ...
- Java设计原则之里氏替换原则
里氏代换原则由2008年图灵奖得主.美国第一位计算机科学女博士Barbara Liskov教授和卡内基·梅隆大学Jeannette Wing教授于1994年提出.其严格表述如下:如果对每一个类型为S的 ...