Control.Category,>>>和<<<是什么意思?

17 haskell arrows category-theory function-composition category-abstractions

我正在关注这个博客,在haskell中编写一个简单的http服务器,

使用情况>>>对我来说并不清楚.这段代码片段做了什么?

handleHttpConnection r c = runKleisli
    (receiveRequest >>> handleRequest r >>> handleResponse) c >>
    close c
Run Code Online (Sandbox Code Playgroud)

在这个链接上,我看到了<<<

let h =     arr (++ "!")
          <<< arr foo
          <<< Kleisli bar
          <<< arr id
Run Code Online (Sandbox Code Playgroud)

做什么<<<和>>>做什么?(Hackage文档非常简洁,无法解决它.)

lef*_*out 21

正如Hackage和/或Hoogle会告诉你的那样,

(>>>) :: Category k => a`k`b  -> b`k`c  -> a`k`c
(<<<) :: Category k => b`k`c  -> a`k`b  -> a`k`c
Run Code Online (Sandbox Code Playgroud)

观察后者实际上是相同的

(.)   :: Category k => b`k`c  -> a`k`b  -> a`k`c
Run Code Online (Sandbox Code Playgroud)

或者,以其Prelude形式,专门用于Hask类别的功能,

(.)   ::               (b->c) -> (a->b) -> (a->c)
Run Code Online (Sandbox Code Playgroud)

所以,<<<与>>>简单地构成的功能,或者更一般地态射/箭头.

<<<组成与熟悉的方向相同的方向.,同时>>>翻转参数,以便"数据从左向右流动".


现在,对于Hask以外的类别,箭头组合的含义当然取决于类别.这是一个易于理解的例子:说我们有一个纯粹的功能Kleisli IO

pipe :: Double -> String
pipe = show . sqrt . (+2) . abs
Run Code Online (Sandbox Code Playgroud)

正如我所说,这也可以写

pipe = abs >>> (+2) >>> sqrt >>> show
Run Code Online (Sandbox Code Playgroud)

现在,如果您想添加原始IO日志记录(就像您可能使用命令式语言),您可以介绍

type (-|>) = Kleisli IO

abs', add2', sqrt' :: Num a => a -|> a
show' :: Show a => a -|> String

abs'  = Kleisli $ \x -> do putStrLn ("Absolute of "++show x++"...")
                           return $ abs x
add2' = Kleisli $ \x -> do putStrLn ("Add 2 to "++show x++"...")
                           return $ x + 2
sqrt' = Kleisli $ \x -> do putStrLn ("Square root of "++show x++"...")
                           return $ sqrt x
show' = Kleisli $ \x -> do putStrLn ("Show "++show x++"...")
                           return $ show x
Run Code Online (Sandbox Code Playgroud)

有了它,你可以定义

pipe' :: Double -|> String
Run Code Online (Sandbox Code Playgroud)

以与以前完全相同的方式,即

pipe' = abs' >>> add2' >>> sqrt' >>> show'
Run Code Online (Sandbox Code Playgroud)

但是现在你将打印出中间结果作为副作用.

  • @MadhavanKumar:嗯,这实际上是`$`无法解决的一个很好的例子:它不能推广到任意类别.([有些类别有`$`的概括,但大多数没有 - 包括`Kleisli`](http://stackoverflow.com/questions/31118949/generalising-like-control-category-generalises/31120454#31120454)除此之外,无点样式通常更简洁,可以更容易重构,并且不需要您引入变量名称...但是,这些并不总是优点; 有时无点理解("无意义的代码"). (3认同)
  • @ imz - IvanZakharyaschev:是的,我想是这样的,只有`> =>`不需要围绕monadic函数的`Kleisli` newtype包装器. (2认同)