2017-12-19 13 views
1

私はいくつかのHaskellの試験紙の質問を練習していて、int型と 二つのリストを受け取り、指定されたサイズの兄貴にそれらを一緒に編むHaskellの関数weaveHunksを定義し、次のHaskell - 2つのリストをnサイズのまとまりでまとめますか?

に遭遇してきました。 型署名を必ず宣言してください。

例:私はあまりにも一緒に2つのだけのリストを織るれるスタックオーバーフロー、上で次を発見した

weaveHunks 3 "ABCDEFGHIJKLMNO" "ABCDEFGHIJKLMNO"

=> "abcABCdefDEFghiGHIjklJKLmnoMNO"

weaveHunks :: [a] -> [a] -> [a] 
weaveHunks xs [] = xs 
weaveHunks [] ys = ys 
weaveHunks (x:xs) (y:ys) = x : y : weaveHunks xs ys 

の塊で、私は、これは、n個のサイズfoのチャンクを取るように調整する問題を抱えています、私はHaskellのが、THIに非常に新しいですsは、私がこれまで持っているもの

weaveHunks :: Int -> [a] -> [a] -> [a] 
weaveHunks n xs [] = xs 
weaveHunks n [] ys = ys 
weaveHunks n xs ys = (take n xs) : (take n ys) : weaveHunks n (drop n xs) (drop n ys) 

である私は、最後の行

(タイプa' with [A] 'と一致しませんでした)

上のエラーを取得しています(drop n xs)ないですリスト?

+0

'weaveHunks'のタイプは、' [a] 'を生成すると言います。タイプシグネチャを除外してghciにロードすると、そのタイプはどのようなものなのでしょうか? – dfeuer

+0

私はタイプシグネチャを削除しました。私はweaveHunks :: p - > [a] - > [a] - > [a] ' –

+0

を与えました。その型情報を取得するには最初の2行を削除する必要があります。とにかく、あなたはあなたの答えを得ました。 – dfeuer

答えて

2

あなたは非常に近いです!

:演算子を使用すると、結果リストの1つの要素であるtake n xsが表示され、take n ysは次のようになります。しかし実際にはどちらの場合も、複数の要素があります。それは実際にはaであるべき[a]です。

解決策は、代わりに++演算子を使用することです。単一の要素ではなく、リスト全体がプリペンドされます。タイプ[a]のあなたの追加リストから

weaveHunks :: Int -> [a] -> [a] -> [a] 
weaveHunks _ xs [] = xs 
weaveHunks _ [] ys = ys 
weaveHunks n xs ys = xHunk ++ yHunk ++ weaveHunks n xRemain yRemain 
where [(xHunk, xRemain), (yHunk, yRemain)] = splitAt n <$> [xs,ys] 
+0

ああ、ありがとう、ありがとう。 <$>の意味は何ですか? –

+0

これはfmapですが、中置演算子です。リストの場合、歴史的な理由からfmap = map。 – HTNW

+0

よろしくお願いいたします。 –

1

@leftaroundaboutが言ったように、あなたの代わりに:++を使用する必要があります。

これは、私はそれを書くだろうと完全なソリューションです。これを念頭に置いて、あなたのコードは次のようになります。

import Data.List.Split 

weaveHunks :: Int -> [a] -> [a] -> [a] 
weaveHunks n xs ys = concat $ zipWith (++) (chunksOf n xs) (chunksOf n ys) 

注:chunksOfData.List.Splitからである

weaveHunks :: Int -> [a] -> [a] -> [a] 
weaveHunks _ xs [] = xs 
weaveHunks _ [] ys = ys 
weaveHunks n xs ys = (take n xs) ++ (take n ys) ++ weaveHunks n (drop n xs) (drop n ys) 

あなたの興味場合は、このタスクを実行するためのライブラリ関数を使用することができますこれはリストを長さがnのサブリストに分割するので、この関数のタイプはInt -> [a] -> [[a]]です。 zipWithは条件に基づいて2つのリストを圧縮します。この場合は連結++です。 concat[[a]]のリストを[a]に変換します。

+1

2つ目のソリューションを根本的に異なるサイズの2つのリストでテストしましたか?ジップは、サイズの不一致でつぶれた尾を切断する傾向があります。 –

関連する問題