2011-03-06 30 views
5

bir tek değere düşürmek için bir öğe listesi üzerinde bir işlem gerçekleştirmek için izin iki işlevi vardır. (Elbette ikiden fazla var, ancak bunlar ilgimi çeken ikisi.) Bunlar foldl1 ve foldr1. Gerçekleştirilecek işlem commutative (ekleme gibi) ise, bunların hangisini kullandığınız önemli değildir. Sonuç aynı olacak. Bununla birlikte, eğer operasyon değiştirici (ör. Çıkarma) değilse, o zaman ikisi çok farklı sonuçlar üretir. Örneğin:J Haskell'in foldl1'inin uygulanmasında en etkili yol nedir? Haskell'de

foldr1 (-) [1..9] 
foldl1 (-) [1..9] 

Birincisi 5 ve ikinciye, -43. foldr1 J eşdeğer uç zarf, /, örneğin, foldr1 (-) [1..9] eşdeğerdir

-/ 1+i.9 

olup. Eklem zarfı gibi çalışan bir J harfini oluşturmak istiyorum, ancak katlar yerine sağa sola. Birlikte gelen en iyi şudur:

- foldl 1+i.9 

ve almak -43 sol kat beklenen budur cevap olarak:

foldl =: 1 : 'u~/@|.' 

Böylece, denebilir.

J bunu yapmanın daha iyi bir yolu var mı? Nedense, y argümanını tersine çevirmek bana etkili gelmiyor. Belki de buna başvurmak zorunda kalmadan bunu yapmanın bir yolu vardır.

+1

olursa olsun görünüyor ne kadar pratik dizi saygısız yanında bir şey olarak böyle olup olmadığını bilmiyorum. Birisi (ya da umut) Haskell'in bunu yapmaz ve sadece işlevin sonuna kadar çalışır ... – MPelletier

+0

"Nasıl IMpractical olursa olsun." – MPelletier

cevap

2

Ben açıkladığınız daha sola kat daha iyi bir yol yoktur sanmıyorum:

(v~)/(|. list) 

Bu çok doğal bir yolu, tanım neredeyse "literal" uygulamasıdır. Listeyi tersine çevirmenin maliyeti çok küçüktür (imo). böylece

foldl_once =: 1 :'(u/0 1 { y), (2}. y)' 
foldl =: 1 :'(u foldl_once)^:(<:#y) y' 

:

sol kat uygulanması diğer belirgin yolu

new_list = (first v second) v rest 

örn ayarlamaktır

- foldl >:i.9 
_43 

ama yolunuzu gerçekleştirir daha iyi çok Bu hem uzayda hem de zamanda.

+0

Size ödül vermeme rağmen, ephemient'in cevabı çok ilginçti, çünkü çözümümün muhtemelen en iyisi olduğunu, bunun kanıtlayamayacağımı düşünüyorum. –

1
($:@}:-{:)^:(1<#) 1+i.9 
_43 

Daha fazla (veya daha az) verimli olup olmadığı hakkında bir fikir yok.

+0

Söylemesi zor. 4500'ün altındaki rakamlarla, çözümünüz ve benimki anlık. Bundan sonra sizinki bir yığın hatasına neden olur ve benimki sadece iyi çalışır. Yani bu anlamda, benimki daha verimlidir, ama kaynaklar bir yana, hangisinin daha hızlı olduğunu söylemek zor. –

+0

Oh, ve ben de seninkilerin hem zeki hem de eğitici olduğunu ekleyeceğimi düşündüm. –

İlgili konular