答えはすでにここで与えられていましたが、(例示的な) 派生ではありません。したがって、これらすべての年月が経過した後でも、おそらく追加する価値があります。
それは実際には非常に簡単です。初め、
フォルダ fz xs
= foldr fz [x1,x2,x3,...,xn] = f x1 (foldr fz [x2,x3,...,xn])
= ... = f x1 (f x2 (f x3 (.. . (f xn z) ...)))
したがって、イータ展開によって、
フォルダ fz xs ys
= foldr fz [x1,x2,x3,...,xn] ys = f x1 (foldr fz [x2,x3,...,xn]) ys
= ... = f x1 (f x2 (f x3 (... (f xn z) ...))) ys
ここで明らかなように、 が 2 番目の引数で非強制的である場合、f最初にx1およびysで機能します。ここで.f x1r1ysr1 =(f x2 (f x3 (... (f xn z) ...)))= foldr f z [x2,x3,...,xn]
だから、使用して
f x1 r1 [] = []
f x1 r1 (y1:ys1) = (x1,y1) : r1 ys1
次のステップとして、残りの入力リスト,を呼び出して、リストに沿って左から右に情報を渡すようにします。そして、それはそれです。 r1ys1foldr f z [x2,x3,...,xn]ys1 = f x2r2ys1
ysより短いxs(または同じ長さ)[]場合、火災の場合fは処理が停止します。しかし、 ifysがxsthenfの[]ケースは起動せず、最終的なアプリケーションに到達します。f xnz(yn:ysn)
f xn z (yn:ysn) = (xn,yn) : z ysn
の終わりに達したためxs、zip処理を停止する必要があります。
z _ = []
これは、次の定義z = const []を使用する必要があることを意味します。
zip xs ys = foldr f (const []) xs ys
where
f x r [] = []
f x r (y:ys) = (x,y) : r ys
の観点からはf、ペアを発行した後、処理を続行するときに呼び出す成功継続rの役割を果たします。f(x,y)
同様に、「より多くの s が存在する場合に、より多くの処理が行われる」と、の-caseはr、「それ以上の sが存在しない場合に行われる処理」です。または、自然に停止し、使い果たされたら戻ることができます。ysxz = const []nilfoldrysxf[]ys
ysが一種の累積値としてどのように使用されているかに注意してください。この値は listxsに沿って左から右へ、ある呼び出しからf次の呼び出しまで渡されます (「蓄積」ステップは、ここでは、そこから head 要素を取り除くことです)。
当然、これは左折に対応し、累積ステップは「関数を適用する」ことであり、 「 sz = idがなくなった」ときに最終的な累積値を返します。x
foldl f a xs =~ foldr (\x r a-> r (f a x)) id xs a
同様に、有限リストの場合、
foldr f a xs =~ foldl (\r x a-> r (f x a)) id xs a
また、結合関数が続行するかどうかを決定するため、早期に停止できる左折畳みが可能になりました。
foldlWhile t f a xs = foldr cons id xs a
where
cons x r a = if t x then r (f a x) else a
またはスキップ左折り、foldlWhen t ...、
cons x r a = if t x then r (f a x) else r a
等