Distributive

class Functor g => Distributive g where
distribute :: Functor f => f (g a) -> g (f a)
distribute = collect id collect :: Functor f => (a -> g b) -> f a -> g (f b)
collect f = distribute . fmap f distributeM :: Monad m => m (g a) -> g (m a)
distributeM = fmap unwrapMonad . distribute . WrapMonad collectM :: Monad m => (a -> g b) -> m a -> g (m b)
collectM f = distributeM . liftM f cotraverse :: (Distributive g, Functor f) => (f a -> b) -> f (g a) -> g b
cotraverse f = fmap f . distribute comapM :: (Distributive g, Monad m) => (m a -> b) -> m (g a) -> g b
comapM f = fmap f . distributeM

Distributive 是个类型类。功能上与 Traversable 类型类呈现对偶(dual)关系。

Traversable 类型将一个函数应用到多个数值,而

Distributive 类型将一个数值应用到多个函数。

((->)e) 是个 Distributive

instance Distributive ((->)e) where
distribute a e = fmap ($e) a
collect f q e = fmap (flip f e) q

Sum 是个 Distributive

instance Distributive Monoid.Sum where
collect = coerce (fmap :: (a -> b) -> f a -> f b)
:: forall f a b . Functor f
=> (a -> Monoid.Sum b) -> f a -> Monoid.Sum (f b)
distribute = Monoid.Sum . fmap Monoid.getSum

应用 Distributive

Prelude Data.Distributive> distribute [(+1),(+2)] 1
[2,3]
Prelude Data.Distributive> collect (^) [1,2] 3
[1,8]
Prelude Data.Distributive> cotraverse sum [(+1),(*2)] 3
10
Prelude Data.Distributive> comapM product [(+1),(*2)] 3
24
Prelude Data.Distributive Data.Monoid> distribute [Sum 1, Sum 2]
Sum {getSum = [1,2]}
Prelude Data.Distributive Data.Monoid> collect (\x->Sum[x]) [3,4]
Sum {getSum = [[3],[4]]}

手动计算

distribute [(+1),(+2)] 1
= fmap ($1) [(+1),(+2)]
= [1+1,1+2] = [2,3]
collect (^) [1,2] 3
= fmap (flip (^) 3) [1,2]
= fmap (^3) [1,2]
= [1^3,2^3] = [1,8]
cotraverse sum [(+1),(*2)] 3
= (fmap sum . distribute) [(+1),(*2)] 3
= sum $ distribute [(+1),(*2)] 3
= sum [4, 6] = 10 这里
(fmap f . g) x y
= (f . g x) y
= f $ g x y

Haskell语言学习笔记(61)Distributive的更多相关文章

  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. jp@gc - Stepping Thread Group 字段说明

    1.   安装好插件 参考文档“扩展Jmeter插件获取更多监听器” 2.   添加线程组 右键测试计划->添加->Threads(Users)->jp@gc - Stepping ...

  2. 用Qstring给char[]数组赋值(转)

    tree_data.Desc  //Desc是char[80]类型的数据 Qstring newDescStr; strcpy(tree_data.Desc , newDescStr.toLocal8 ...

  3. 启动servlet报错:The servlets named [DemoServlet] and [main.java.com.wlf.demo.servlet.DemoServlet] are both mapped to the url-pattern [/hello] which is not permitted

    先看具体错误日志: [2019-04-26 09:29:25,484] Artifact demo-servlet:war: Artifact is being deployed, please wa ...

  4. yield对性能提升的一次小小测试

    生成器提供了一种更容易的方法来实现简单的对象迭代,相比较定义类实现 Iterator 接口的方式,性能开销和复杂性大大降低.生成器允许你在 foreach 代码块中写代码来迭代一组数据而不需要在内存中 ...

  5. 切图js

    首先引用一段关于拖动,缩放,剪切的基础代码 /* * 作者:http://cloudgamer.cnblogs.com/ * * 改进与增强 * 作者:http://yoker.sc0826.com/ ...

  6. ios之gcd

    看这里吧 http://www.jianshu.com/p/3a5a55e50e84

  7. Mysql 性能优化1 硬件设备的选择

    --------------------------------------------目录------------------------------------------------- • 我们 ...

  8. jq 获取name值一样的数组

    <input type="text" value="" name="wid"/><input type="tex ...

  9. 合并Dev BPL教程

    一.准备工具 1.Devexpress vcl 14.2.2 下载地址http://download.csdn.net/user/rfjbco,共用个包,下载后解压,程序目录已带有DxAutoInst ...

  10. java操作Excel之POI(6)使用POI实现使用模板批量添加数据

    action是用struts2写的:前端界面easyUI写的, 前端: <!DOCTYPE html> <html> <head> <meta charset ...