自动将中缀运算符提升为单元中缀运算符
Haskell 的优点之一是能够使用中缀表示法。
1 : 2 : 3 : [] :: Num a => [a]
2 + 4 * 3 + 5 :: Num a => a
但当操作员需要被抬起时,这种力量突然而悲伤地消失了。
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
,但是需要重命名我想在单子上下文中使用的每个运算符是很乏味的。有更好的办法吗?也许是 Haskell 模板?
One of the nice things about Haskell is the ability to use infix notation.
1 : 2 : 3 : [] :: Num a => [a]
2 + 4 * 3 + 5 :: Num a => a
But this power is suddenly and sadly lost when the operator needs to be lifted.
liftM2 (*) (liftM2 (+) m2 m4) (liftM2 (+) m3 m5)
liftM2 (:) m1 (liftM2 (:) m2 (liftM2 (:) m3 mE))
It is possible to define similar operators in order to regain this power
(.*) = 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
But it is tedious to need to rename every operator I want to use in a monadic context. Is there a better way? Template Haskell, perhaps?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
您可以创建
Num
: 的所有 monad 实例:然后您可以执行 fe:
但这仅适用于使用类型类定义的运算符。对于
:
这是不可能的。You can make all monads instances of
Num
:Then you can do f.e.:
But this only works for operators that are defined with type classes. With
:
this isn't possible.您可以定义一个新的中缀提升:
使用示例:
...但我不知道有什么真正的方法不是 100% 烦人。
You can define a new infix lift:
Example use:
...but I don't know of any real way that isn't 100% annoying.
有使用
ap
的样式:或 applicative 样式:
There is the style using
ap
:or applicative style: