将非monadic函数绑定到monad

F. *_*ler 2 monads haskell function-composition

也许这是一个经常被问到的问题,但我没有找到答案.

monad的绑定定义如下:

(>>=)  :: m a -> (a -> m b) -> m b
Run Code Online (Sandbox Code Playgroud)

目前我正在这样做:

foo :: Int
foo = sum $ ((*11) . (+2)) `map` [1..4]
Run Code Online (Sandbox Code Playgroud)

我想实现这样的语法,因为我认为它更具可读性:

[1..4] >>= (+2) >>= (*11) >>= sum
Run Code Online (Sandbox Code Playgroud)

我不知道合适的运营商而不是>>=.

此外:foo是198.

lef*_*out 9

在这种情况下最可读的当然是

   sum [ (x+2)*11 | x<-[1..4] ]
Run Code Online (Sandbox Code Playgroud)

但如果你想要它没有点,没有额外的parens,只需用infix fmap运算符重写原始行:

   sum $ (*11) . (+2) <$> [1..4]
Run Code Online (Sandbox Code Playgroud)

如果你只是想扭转的顺序,可以取代.具有同等翻转操作Control.Category,并$其翻转版本例如,从lens

   [1..4] & fmap((+2)>>>(*11)) & sum
Run Code Online (Sandbox Code Playgroud)

再说一遍,如果你追求数学优雅并希望它"像monad一样工作",这是不可能的,因为这里没有任何monadic.然而,你可以认为这sum是一个Cokleisli箭头(不可定义,在Haskell 98中) - Monoid限制列表comonad.我们可以通过NonEmpty comonad来估算这个并写

    extract $ fromList [1..4] =>> (extract>>>(+2)>>>(*11)) =>> sum.toList
Run Code Online (Sandbox Code Playgroud)

但这太荒谬了.

  • 如有疑问,只需在Monoid-limited list comonad*中使用*Cokleisli箭头.:-) (2认同)
  • 什么是monoid限制列表? (2认同)