2012-03-09 46 views
3

考慮如何在這裏使用箭頭?

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

忽略了一個事實,這可以很容易地使用elem寫的,我有我可以採用Arrow語法簡化拉姆達的強烈的感覺,我只是無法得到它的權利。

這個lambda可以用箭頭簡化嗎?你有什麼關於如何「看」箭頭可能工作的一般提示,以及如何找到正確的表達方式?

+1

愛德華Kmett解放出來我從需要關心箭頭3周股份公司o [在布蘭登西蒙斯的博客上有這些評論](http://brandon.si/code/categories-that-want-to-be-arrows/#comment-437318026)。 – 2012-03-09 19:51:27

+1

@DanielLyons儘管如此,由於箭頭的功能實例,典型的箭頭組合符&&&','|||'和'***'可以是有用的。 – 2012-03-09 22:01:43

+0

同意。我只是不認爲真正的回報,充分理解他們證明了這種痛苦。 – 2012-03-09 23:12:45

回答

7

拉出計算出foldr相似的 -

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

但是,如果你想確保你只穿過一次名單,請嘗試使用bifunctor package

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

或更短:元素2 &&& elem 7 $ [1..6]' – Landei 2012-03-09 22:58:15

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

我不認爲你可以用箭頭抽象出x

編輯:嗯,好像你可以:

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

'(||)'是一個被香蕉托架包圍的空表達式嗎? ;-) – Andre 2012-03-09 15:31:07

+1

如果消歧確實是必要的,你可以總是給它更多的空格:'(||)'。但是使用6個字符來表示2個字符的操作符是非常殘酷的。 – 2012-03-09 22:14:55

+0

即使解決方案看起來不太可愛,我也會記住'uncurry(***)'技巧。謝謝! – Landei 2012-03-11 17:12:28