amo*_*ebe 7 refactoring haskell pointfree do-notation
我想在Haskell中依次组合两个monad动作,丢弃第二个动作产生的任何值,并将参数传递给两个动作.目前我正在使用这样的do-block:
ask = do
result <- getLine
putStrLn result
return result
Run Code Online (Sandbox Code Playgroud)
我本来希望写一点免费和整洁,所以我尝试了这个:
ask' = getLine <* putStrLn
Run Code Online (Sandbox Code Playgroud)
但是,这甚至不进行类型检查,问题是<*不会将第一个动作的结果传递给第二个动作.我希望将操作链接起来>>=,但不会更改结果.类型应该是(a -> m b) -> (a -> m c) -> (a -> m b),但Hoogle没有产生合适的结果.实现此功能组合的操作员是什么?
作为一种趋势,如果你在两个不同的地方使用一个值,那么在一个明确的块中给它起一个名字可能是一个好主意do,而不是按下毫无意义的风格.
将信息流分解为不同动作的抽象概念由笛卡尔幺半群类别捕获,Haskellers将其称为箭头.在您的情况下,您基本上是在IOKleisli类别中工作:
import Prelude hiding (id)
import Control.Arrow
ask' :: Kleisli IO () String
ask' = Kleisli (\()->getLine) >>> (putStrLn &&& id) >>> arr snd
Run Code Online (Sandbox Code Playgroud)
我不认为编写这样的代码是个好主意.