¿Cómo uso las flechas aquí?

Imagine

foldr (\x (a,b) -> (a || x==2, b || x==7 )) (False,False) [1..6]
--(True,False)

Ignoring the fact that this could be written easily using elem, I have the strong feeling that I could employ Arrow syntax to simplify the lambda, I just can't get it right.

Can this lambda be simplified using arrows? And do you have any general hints concerning how to "see" when arrows might work, and how to find the right expression?

preguntado el 09 de marzo de 12 a las 14:03

Edward Kmett liberated me from my need to care about arrows three weeks ago with these comments on Brandon Simmons's blog. -

@DanielLyons nevertheless, the typical arrow combinators &&&, ||| y *** can be useful because of the function instance of arrow. -

Agreed. I just don't think the payoff for truly, fully understanding them justifies the pain. -

2 Respuestas

Pull the computation out of the foldr -

ghci> :m +Control.Arrow
ghci> any (==2) &&& any (==7) $ [1..6]
(True,False)

But if you want to be sure you're only traversing the list once, try using the bifunctor package:

ghci> :m +Data.Bifunctor +Data.Bifunctor.Apply
ghci> foldr (bilift2 (||) (||) . ((==2) &&& (==7))) (False, False) [1..6]
(True,False)

respondido 10 mar '12, 12:03

O más corto: elem 2 &&& elem 7 $ [1..6] - Landéi

foldr (\x -> (|| x==2) *** (|| x==7)) (False,False) [1..6]

I don't think you can abstract the x out with arrows.

Edit: well, seems like you can:

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

respondido 09 mar '12, 15:03

Is (||) an empty expression surrounded by banana brackets? ;-) - Andre

If disambiguation is indeed necessary, you can always give it more whitespace: ( || ). But using 6 characters to refer to a 2-character operator is atrocious. - Dan Burton

Even if the solution doesn't look very cute, I'll keep the uncurry (***) trick in mind. Thanks! - Landéi

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.