Haskell语言学习笔记(40)Arrow(1)
来源:互联网 发布:数组强制类型转换 编辑:程序博客网 时间:2024/06/06 19:58
Arrow
class Category a => Arrow a where arr :: (b -> c) -> a b c first :: a b c -> a (b,d) (c,d) first = (*** id) second :: a b c -> a (d,b) (d,c) second = (id ***) (***) :: a b c -> a b' c' -> a (b,b') (c,c') f *** g = first f >>> arr swap >>> first g >>> arr swap where swap ~(x,y) = (y,x) (&&&) :: a b c -> a b c' -> a b (c,c') f &&& g = arr (\b -> (b,b)) >>> f *** g
Arrow(箭头)是个类型类,它是 Category(范畴)的子类。
Arrow 是函数的进一步抽象。
* arr :: (b -> c) -> a b c
arr 函数将函数转换为 Arrow。
* first :: a b c -> a (b,d) (c,d)
first 函数接收两个参数,但是只修改第一个参数。
* second :: a b c -> a (d,b) (d,c)
second 函数接收两个参数,但是只修改第二个参数。
* (***) :: a b c -> a b’ c’ -> a (b,b’) (c,c’)
(***) 函数接收两个参数,然后分别使用两个 Arrow 来修改这两个参数。
* (&&&) :: a b c -> a b c’ -> a b (c,c’)
(&&&) 函数只接收一个参数,拷贝一份,然后分别使用两个 Arrow 来修改这两个同样的参数。
Arrow 的法则
arr id = idarr (f >>> g) = arr f >>> arr gfirst (arr f) = arr (first f)first (f >>> g) = first f >>> first gfirst f >>> arr fst = arr fst >>> ffirst f >>> arr (id *** g) = arr (id *** g) >>> first ffirst (first f) >>> arr assoc = arr assoc >>> first f where assoc ((a,b),c) = (a,(b,c))
(->) 是个 Arrow
instance Arrow (->) where arr f = f (***) f g ~(x,y) = (f x, g y)
Prelude Control.Arrow> (+2) &&& (*2) $ 3(5,6)Prelude Control.Arrow> (+2) *** (*2) $ (1,3)(3,6)Prelude Control.Arrow> (+2) <<< (*2) $ 38Prelude Control.Arrow> first (*2) (1,3)(2,3)Prelude Control.Arrow> second (*2) (1,3)(1,6)Prelude Control.Arrow> arr (*2) 36
Kleisli Arrow
newtype Kleisli m a b = Kleisli { runKleisli :: a -> m b }instance Monad m => Category (Kleisli m) where id = Kleisli return (Kleisli f) . (Kleisli g) = Kleisli (\b -> g b >>= f)instance Monad m => Arrow (Kleisli m) where arr f = Kleisli (return . f) first (Kleisli f) = Kleisli (\ ~(b,d) -> f b >>= \c -> return (c,d)) second (Kleisli f) = Kleisli (\ ~(d,b) -> f b >>= \c -> return (d,c))
Kleisli m a b封装了一个返回值为 Monad 的函数:a -> m b。
如果 m 是 Monad,那么 Kleisli m 是 Category,也是 Arrow。
Prelude Control.Arrow> runKleisli ((Kleisli (\x -> [x * 2])) >>> (Kleisli (\x -> [x, -x]))) 2[4,-4]Prelude Control.Arrow Control.Monad> (\x -> [x * 2]) >=> (\x -> [x, -x]) $ 2[4,-4]
Arrow 的函数
returnA :: Arrow a => a b breturnA = arr id(^>>) :: Arrow a => (b -> c) -> a c d -> a b df ^>> a = arr f >>> a(>>^) :: Arrow a => a b c -> (c -> d) -> a b da >>^ f = a >>> arr f(<<^) :: Arrow a => a c d -> (b -> c) -> a b da <<^ f = a <<< arr f(^<<) :: Arrow a => (c -> d) -> a b c -> a b df ^<< a = arr f <<< a
阅读全文
0 0
- Haskell语言学习笔记(40)Arrow(1)
- Haskell语言学习笔记(47)Arrow(2)
- Haskell语言学习笔记(1)
- Haskell语言学习笔记(2)
- Haskell语言学习笔记(4)Functor
- Haskell语言学习笔记(5)Applicative
- Haskell语言学习笔记(6)Monad
- Haskell语言学习笔记(8)Monoid
- Haskell语言学习笔记(14)Foldable
- Haskell语言学习笔记(16)Alternative
- Haskell语言学习笔记(17)MonadPlus
- Haskell语言学习笔记(18)Traversable
- Haskell语言学习笔记(21)Array
- Haskell语言学习笔记(22)MaybeT
- Haskell语言学习笔记(29)CPS
- Haskell语言学习笔记(31)ListT
- Haskell语言学习笔记(35)Contravariant
- Haskell语言学习笔记(39)Category
- Android 解决图片大量下载:软引用必须懂4点
- android-监听网络状态
- ImportError: numpy.core.multiarray failed to import
- android几种定时器机制及区别
- android获取手机录
- Haskell语言学习笔记(40)Arrow(1)
- android开发分辨率问题解决方案
- 本地Mysql服务无法启动
- 开发移动app与服务器端session的状态管理与交互
- Android利用canvas画各种图形(点、直线、弧、圆、椭圆、文字、矩形、多边形、曲线、圆角矩形)
- android string.xml %问题
- android开发中系统自带语音模块的使用
- 自动输入密码、命令 expect
- TextSwitcher,译为文字转换器控件