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)
不是我推荐这个。
我最近有幸学习了一些 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)
不是我推荐这个。