Haskell的优点之一是可以使用中缀表示法。
1 : 2 : 3 : [] :: Num a => [a]
2 + 4 * 3 + 5 :: Num a => a
但是,当需要抬起运算符(operator)时,这种力量突然而可悲地失去了。
liftM2 (*) (liftM2 (+) m2 m4) (liftM2 (+) m3 m5)
liftM2 (:) m1 (liftM2 (:) m2 (liftM2 (:) m3 mE))
可以定义类似的运算符以重新获得此功能
(.*) = liftM2 (*)
(.+) = liftM2 (+)
(.:) = liftM2 (:)
m1, m2, m3, m4, m5 :: Monad m, Num a => m a
mE = return [] :: Monad m => m [a]
m1 .: m2 .: m3 .: mE :: Monad m, Num a => m [a]
m2 .+ m4 .* m3 .+ m5 :: Monad m, Num a => m a
但是,需要重命名我想在单子(monad)上下文中使用的每个运算符都是很麻烦的。有没有更好的办法?模板Haskell,也许吗?
最佳答案
您可以定义一个新的infix提升:
v <. f = liftM2 f v
f .> v = f v
使用示例:
[3] <.(+).> [4]
...但是我不知道有没有100%令人讨厌的真实方法。