Haskell 这里如何使用箭头?

Haskell 这里如何使用箭头?,haskell,arrows,Haskell,Arrows,考虑 foldr (\x (a,b) -> (a || x==2, b || x==7 )) (False,False) [1..6] --(True,False) 忽略使用elem可以轻松编写这一事实,我强烈感觉可以使用Arrow语法来简化lambda,我就是做不好 可以使用箭头简化此lambda吗?关于如何“看到”箭头何时起作用,以及如何找到正确的表达式,您有什么一般性的提示吗 foldr (\x -> (|| x==2) *** (|| x==7)) (False,False

考虑

foldr (\x (a,b) -> (a || x==2, b || x==7 )) (False,False) [1..6]
--(True,False)
忽略使用
elem
可以轻松编写这一事实,我强烈感觉可以使用
Arrow
语法来简化lambda,我就是做不好

可以使用箭头简化此lambda吗?关于如何“看到”箭头何时起作用,以及如何找到正确的表达式,您有什么一般性的提示吗

foldr (\x -> (|| x==2) *** (|| x==7)) (False,False) [1..6]
我认为你不能用箭头把
x
抽象出来

编辑:看来你可以:

foldr (uncurry (***) . (((||) . (==2)) &&& ((||) . (==7)))) (False,False) [1..6]

将计算从文件夹中拉出-

ghci> :m +Control.Arrow
ghci> any (==2) &&& any (==7) $ [1..6]
(True,False)
但如果要确保只遍历列表一次,请尝试使用:


(| |)
是一个被香蕉括号包围的空表达式吗?;-)如果确实需要消除歧义,您可以始终为其提供更多的空白:
(| |)
。但是使用6个字符来表示2个字符的运算符是非常糟糕的。即使解决方案看起来不是很可爱,我也会记住
uncurry(***)
技巧。谢谢Edward Kmett三周前把我从关心箭头的需要中解放出来了。@DanielLyons然而,典型的箭头组合器
&&&
| |
***
可能很有用,因为arrow.com的函数实例。我只是不认为真正、充分理解它们的回报可以证明痛苦是合理的。或者更简短地说:
elem 2&&elem 7$[1..6]
ghci> :m +Data.Bifunctor +Data.Bifunctor.Apply
ghci> foldr (bilift2 (||) (||) . ((==2) &&& (==7))) (False, False) [1..6]
(True,False)