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的更多相关文章

  1. Haskell语言学习笔记(88)语言扩展(1)

    ExistentialQuantification {-# LANGUAGE ExistentialQuantification #-} 存在类型专用的语言扩展 Haskell语言学习笔记(73)Ex ...

  2. Haskell语言学习笔记(79)lambda演算

    lambda演算 根据维基百科,lambda演算(英语:lambda calculus,λ-calculus)是一套从数学逻辑中发展,以变量绑定和替换的规则,来研究函数如何抽象化定义.函数如何被应用以 ...

  3. Haskell语言学习笔记(69)Yesod

    Yesod Yesod 是一个使用 Haskell 语言的 Web 框架. 安装 Yesod 首先更新 Haskell Platform 到最新版 (Yesod 依赖的库非常多,版本不一致的话很容易安 ...

  4. Haskell语言学习笔记(20)IORef, STRef

    IORef 一个在IO monad中使用变量的类型. 函数 参数 功能 newIORef 值 新建带初值的引用 readIORef 引用 读取引用的值 writeIORef 引用和值 设置引用的值 m ...

  5. Haskell语言学习笔记(39)Category

    Category class Category cat where id :: cat a a (.) :: cat b c -> cat a b -> cat a c instance ...

  6. Haskell语言学习笔记(72)Free Monad

    安装 free 包 $ cabal install free Installed free-5.0.2 Free Monad data Free f a = Pure a | Free (f (Fre ...

  7. Haskell语言学习笔记(44)Lens(2)

    自定义 Lens 和 Isos -- Some of the examples in this chapter require a few GHC extensions: -- TemplateHas ...

  8. Haskell语言学习笔记(38)Lens(1)

    Lens Lens是一个接近语言级别的库,使用它可以方便的读取,设置,修改一个大的数据结构中某一部分的值. view, over, set Prelude> :m +Control.Lens P ...

  9. Haskell语言学习笔记(92)HXT

    HXT The Haskell XML Toolbox (hxt) 是一个解析 XML 的库. $ cabal install hxt Installed hxt-9.3.1.16 Prelude&g ...

随机推荐

  1. npm 构建时,次要版本变化引起的问题

    问题:下载项目后,运行 npm install 或 yarn install,vue-awesome-swiper 做的功能显示不正常. 解决:从 官方网站 文件 README.md 中找到: // ...

  2. logging 的配置和使用

    logging 的配置和使用 reference : logging cookbook logging HOWTO 测试源码,example import logging nt = 'xwei' # ...

  3. JS 响应式布局

    1.media 效果为屏幕宽度变化时,背景颜色也变化 <!DOCTYPE html> <html lang="en"> <head> <m ...

  4. kvm 基本运维命令

    Kvm基本命令 一.查询命令 1.列出所有的虚拟机 virsh list –all 2.显示虚拟机信息 virsh dominfo kvm-1 3.显示虚拟机内存和cpu的使用情况 yum insta ...

  5. 【python】网络编程-UDP协议套接字

    服务器端: #!/usr/bin/env python from socket import * from time import ctime HOST = '' PORT = 21567 BUFSI ...

  6. TFS错误-TF249053

    前几天规划了下代码结构,改了很多东西后,台式机依然正常访问,但是笔记本一连接或者更改TFS相关资源就报错TF249053.报错点击后不影响正常使用,但是很郁闷.于是查了下资料如下. 错误原因: htt ...

  7. 过度使用DBLINK做系统集成会带来的问题

    过度使用DBLINK做系统集成会带来很多问题,问题主要由以下几点: 1. 大量消耗数据库资源: 本地系统每通过DBLINK链接远端系统一次,都会生成一个本地session,如本地session不退出或 ...

  8. [UE4]C++调用蓝图函数:BlueprintImplementableEvent函数说明符用法

    用BlueprintImplementableEvent标明的函数在C++代码中不需要有方法体,方法体在蓝图中实现. 用法: 1,现在C++头文件中定义函数名 UFUNCTION(BlueprintI ...

  9. Scrapyd发布爬虫的工具

    Scrapyd Scrapyd是部署和运行Scrapy.spider的应用程序.它使您能够使用JSON API部署(上传)您的项目并控制其spider. Scrapyd-client Scrapyd- ...

  10. PCIe Max_Payload_Size 和 Max_Read_Request_Size

    最近PCIe在SSDFans上镜率挺高,那我们来聊两句MAX_READ_REQUEST_SIZE 和MAX_PAYLOAD_SIZE. 这两个东西都在PCIe Capability Structure ...