Haskell 版本的 Idris !-notation(爆炸符号)

Haskell version of Idris !-notation (bang notation)

我最近有幸学习了一些 Idris,我发现非常方便的一件事是 !-notation,它让我缩短了 do 块中的 monadic 代码,例如

a' <- a
b' <- b
c' <- c
someFunction a' b' c'

变得更好

someFunction !a !b !c

现在,当我在 Haskell 中编写代码时,我正在寻找类似的东西,但据我所知它不存在(并且 bang 字符显然已经用于严格的模式匹配) .有什么方法可以避免在 do 块中出现一堆琐碎的向左箭头?也许是一个添加重写规则的扩展,或者类似的东西?

因为每个 monad 都是一个 Applicative(GHC >= 7.10)我们可以写成

someFunction <$> a <*> b <*> c

请注意,如果 someFunction return 是类型 m T 的单子值,则上述内容将 return m (m T),这可能不是我们想要的(正如@pigworker 在下面指出的那样)。然而,我们可以 join 将两层放在一起:

join $ someFunction <$> a <*> b <*> c

@chi 的答案的替代方法是 liftA3 someFunction a b c(如果需要,可以使用 join)。

说到箭...

import Control.Arrow

a' = Kleisli $ const a
b' = Kleisli $ const b
c' = Kleisli $ const c

foo = (`runKleisli`()) $
  (a' &&& b') &&& c' >>> uncurry (uncurry someFunction)

不是我推荐这个。