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. opencv中的更通用的形态学

    为了处理更为复杂的情况,opencv中还支持更多的形态学变换. 形态学名称 操作过程 操作名称 是否需要temp参数 开操作 open open(src)=先腐蚀,后膨胀  CV_MOP_OPEN 否 ...

  2. Flask请求处理流程(request)[待续]

    WSGI简介 WSGI(全称Web Server Gateway Interface),是为 Python 语言定义的Web服务器和Web应用程序之间的一种简单而通用的接口,它封装了接受HTTP请求. ...

  3. C/C++动态分配连续空间,下标越界导致的free():invalid next size问题

    昨天帮导师做的一个程序出了内存泄露的bug(在VS上程序运行一切正常,等return返回后才出错) 而且是程序运行结束后才出现的错误,在退出前一切代码都顺利执行完了,只是return之后出错. 之后我 ...

  4. php curl模拟登录(半转载)

    参考:http://our2848884.blog.163.com/blog/static/146854834201282039334/   php curl模拟登录 参考:http://blog.c ...

  5. SpringCloud使用jpa之Rest方式

    这个与上一篇的基本相同,需要修改的只有Dao层的文件: TablesDao.java package com.shinho.dao; import org.springframework.data.j ...

  6. JavaScript之图片操作4

    本次要实现的效果是,在一个盒子里面有一张长图,只显示了一部分,为方便用户浏览,当鼠标移入时,图片开始滚动,将盒子分成上下两部分,当鼠标移入上部分时,图片向上滚动,当鼠标移入下部分时,图片向下滚动. 为 ...

  7. 学习笔记之Moq

    dotnet/src/MoqSample at master · haotang923/dotnet · GitHub https://github.com/htanghtang/dotnet/tre ...

  8. 廖雪峰Java1-2Java程序基础-3整数运算

    1.四则运算规则 int i =(100 + 200) * (99 -88);//3300 int n = i + 9;//3309 //除法结果为整数 int q = n / 100;//33 // ...

  9. 如何使input双击时不显示历史记录

    原文地址:http://highping.iteye.com/blog/359428 HTML的输入框可以拥有自动完成的功能,当你往输入框输入内容的时候,浏览器会从你以前的同名输入框的历史记录中查找出 ...

  10. 文字和img、input并排无法对齐的问题

    文字和img.input并排在一行的时候,img和input位置总是会偏移一点,input就用复选框和按钮举例,如下图: 只要在img和input样式加上vertical-align:middle;就 ...