2011-12-12 13 views
10

2つの整数のリストを取り、2つのリストから交互に取られた要素を持つリストを生成する関数haskellを作成しようとしています。Haskell - 2つのリストから要素を交互に返す

私が機能を持っている:

blend xs ys 

例:

blend [1,2,3] [4,5,6] 

[1,4,2,5,3,6] 

私のロジックは、代替のペアを生成し、2つのリストを圧縮することである返す必要がありますそれらのタプルからそれらを削除します。

タプルから削除しているため、実装方法がわかりません。

答えて

18

再帰 - 降下中に引数を交換するのはどうですか?

blend (x:xs) ys = x:(blend ys xs) 
blend _ _ = [] 

あなたも、リストの任意の数のためにこのアプローチを一般化(私はあなたにこれを残しておきます)、または他が空の場合、リストの残りの要素を取ることができます。

blend _ ys = ys 
+0

非常にクールな方法です!ありがとう。 – Shabu

6

私がしますこれが宿題であると仮定してください。 (あなたが言ったように)提供あなたが以下のリストを作成することができます:

  1. あなたがリスト[a, b]にタプル(a, b)を変換する必要があります。

    [(1,4),(2,5),(3,6)] 
    

    ...あなたは、2つの機能でそれを解決することができます。パターンマッチングを試してみてください!この関数は、あなたが持っているリストのすべての要素に適用される必要があります。

  2. [[1,4],[2,5],[3,6]]のようなリストのリストがあるので、サブリストを1つの大きなリストに連結する機能が必要です。

もちろん、この問題を解決するにはその他の、おそらく優れた方法がありますが、独自のアプローチを続けるとよいでしょう。

+1

私は、(方向が完全に間違っていない限り、この場合はそうではない)元の方向に続く「[宿題]」の質問に対する回答が特に役立つと思います。 –

4

あなたの代わりにタプルのリストを生成、圧縮する場合:

concat $ zipWith (\x y -> [x,y]) [1,2,3] [4,5,6] 

いくつかの無意味な楽しみ:

concat $ zipWith ((flip(:)).(:[])) [1,2,3] [4,5,6] 

おそらく最も簡単な方法:

import Data.List 
concat $ transpose [[1,2,3],[4,5,6]] 
2

液を用いずにconcatまたは明示的な再帰:

blend l = foldr($)[] . zipWith(.) (map(:)l) . map(:) 

我々はまた、作ることができます。この時点フリーどのように動作する

blend' = (foldr($)[].) . (.map(:)) . zipWith(.) . map(:) 


:最初

\[1,2,3] [4,5,6] -> [1:, 2:, 3:] [4:, 5:, 6:] 

は、その後、我々は機能組成物と、この一緒にジップ短所事業者との両方のリストを飾ります

最後にこれらすべての組成物を右から空のリストに折りたたみます

-> (1:).(4:) $ (2:).(5:) $ (3:).(6:) $ [] = 1:4:2:5:3:6:[] = [1,4,2,5,3,6] 
+0

これは何が問題なのですか? – leftaroundabout