Как здесь использовать стрелки?

Учитывать

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

Игнорируя тот факт, что это можно легко написать с помощью elem, у меня есть сильное ощущение, что я мог бы использовать синтаксис Arrow для упрощения лямбды, но я просто не могу понять это правильно.

Можно ли упростить эту лямбду с помощью стрелок? И есть ли у вас какие-то общие подсказки, как «увидеть», когда стрелки могут сработать, и как найти правильное выражение?


person Landei    schedule 09.03.2012    source источник
comment
Эдвард Кметт освободил меня от необходимости заботиться о стрелах три недели назад с этими комментариями в блоге Брэндона Симмонса.   -  person Daniel Lyons    schedule 09.03.2012
comment
@DanielLyons, тем не менее, типичные комбинаторы стрелок &&&, ||| и *** могут быть полезны из-за экземпляра функции стрелки.   -  person Dan Burton    schedule 10.03.2012
comment
Согласованный. Я просто не думаю, что вознаграждение за истинное, полное понимание их оправдывает боль.   -  person Daniel Lyons    schedule 10.03.2012


Ответы (2)


Вытащите вычисление из папки -

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

Но если вы хотите быть уверены, что просматриваете список только один раз, попробуйте использовать пакет bifunctor. :

ghci> :m +Data.Bifunctor +Data.Bifunctor.Apply
ghci> foldr (bilift2 (||) (||) . ((==2) &&& (==7))) (False, False) [1..6]
(True,False)
person rampion    schedule 09.03.2012
comment
Или короче: elem 2 &&& elem 7 $ [1..6] - person Landei; 10.03.2012

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

Я не думаю, что вы можете абстрагировать x стрелками.

Изменить: ну, похоже, вы можете:

foldr (uncurry (***) . (((||) . (==2)) &&& ((||) . (==7)))) (False,False) [1..6]
person Sjoerd Visscher    schedule 09.03.2012
comment
Является ли (||) пустым выражением, окруженным банановыми скобками? ;-) - person Andre; 09.03.2012
comment
Если устранение неоднозначности действительно необходимо, вы всегда можете добавить больше пробелов: ( || ). Но использовать 6 символов для обозначения 2-символьного оператора — это ужасно. - person Dan Burton; 10.03.2012
comment
Даже если решение не выглядит очень симпатичным, я буду помнить о uncurry (***) трюке. Спасибо! - person Landei; 11.03.2012