2017-09-02 5 views
1

私はリストを逆にする方法を知っていますが、foldlを使ってより効率的にしようとしています。私のコードは次の通りです:foldlを使用してHaskellのリストを逆転させない

GHCiで実行すると、入力と同じリストが返されます。何がうまくいかない?私もfoldrでそれを終了しようとするが、それは変更を表示しません。

+0

は[Haskellではリストをリバース](HTTPSのhttps://stackoverflow.com/questions/26847192/reverse-a-list-in-haskell – icc97

+0

可能な複製を参照してください。 ://stackoverflow.com/questions/26847192/reverse-a-list-in-haskell) – icc97

+0

@ icc97正しい 'foldl'解決法がその質問に与えられていますが、質問自体は実際にはそうではありません。それは重複していると言います。 – leftaroundabout

答えて

3

foldlは、ファンクションの最初の引数としてアキュムレータを渡します。 ++は最初の引数を2番目の引数に連結しますが、リストを逆にするには2番目のものを最初のものに連結する必要があります。代わりに最初の、あなたは短所(:)機能を使用することができます(同様に高価である)シングルトンリストにリストのすべての要素を変換するの

Prelude> let reverse list = foldl (flip (++)) [] (map (\x -> [x]) list) 
Prelude> reverse [1..5] 
[5,4,3,2,1] 
+0

"concatenates ... to"は無指向性です。混乱する。 "before"ははるかに良いでしょう。 –

3

:あなたはこのflip (++)を使用して操作を行うことができ

reverse :: Foldable t => t a -> [a] 
reverse = foldl (flip (:)) [] 

ので、ここでは折り畳み機能としてflip (:) :: [a] -> a -> [a]を使用します。テールは[a]と頭部はaで、最初の要素として頭部を、最後の要素としてテールを持つリストを構成します。

だから何が起こるかです:

foldl (flip (:)) [] [1,4,2,5] 
-> foldl (flip (:)) (1:[]) [4,2,5] 
-> foldl (flip (:)) (4:1:[]) [2,5] 
-> foldl (flip (:)) (2:4:1:[]) [5] 
-> foldl (flip (:)) (5:2:4:1:[]) [] 
-> (5:2:4:1:[]) 
-> [5,2,4,1] 
+0

私はいつもfoldlとfoldrの違いに苦しんでいます、なぜfoldlをここで使うのですか?あなたは簡単な説明を気にしますか?ありがとう! – Netwave

+0

@DanielSanchez: 'foldr'は、リストの右端(またはより一般的な折り畳み可能部分)を開始します。リストが '[a、b、c、d]'ならば、 'f a(f b(f d z)))'を計算します。一方、 'foldl'は' f(f(f z a)b)c)d 'を計算します。 'z'は初期要素'となります。 –

+0

よろしくお願いします。ありがとうございました! – Netwave

関連する問題