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