[1,2,4,5,6,7]
手動で に分割するにはどうすればよい[[1],[2],[3],[4],[5],[6],[7]]
ですか? 手動とは、ブレークを使用しないことを意味します。
では、述語に従ってリストをサブリストに分割するにはどうすればよいでしょうか。そのようです
f even [[1],[2],[3],[4],[5],[6],[7]] == [[1],[2,3],[4,5],[6,7]]
PS: これは宿題ではありません。私は何時間もかけて自分で解決しようとしました。
[1,2,4,5,6,7]
手動で に分割するにはどうすればよい[[1],[2],[3],[4],[5],[6],[7]]
ですか? 手動とは、ブレークを使用しないことを意味します。
では、述語に従ってリストをサブリストに分割するにはどうすればよいでしょうか。そのようです
f even [[1],[2],[3],[4],[5],[6],[7]] == [[1],[2,3],[4,5],[6,7]]
PS: これは宿題ではありません。私は何時間もかけて自分で解決しようとしました。
最初の質問に答えると、これは分割ではなく要素ごとの変換です。これを行う適切な関数は次のとおりです。
map :: (a -> b) -> [a] -> [b]
ここで、要素を同じ型を含むシングルトン リストに変換するため、関数(a -> b)
where b
is が必要です。[a]
ここにあります:
mkList :: a -> [a]
mkList a = [a]
それで
map mkList [1,2,3,4,5,6,7] == [[1],[2],...]
2 番目の質問について: の使用が許可されていない場合 (宿題ですか?) 、 の結果の両方の半分を形成するとbreak
を使用することは許可されていますか?takeWhile
dropWhile
break
とにかく、それらを使わずに (「手動で」) 解決するには、アキュムレータを使用して単純な再帰を使用するだけです。
f p [] = []
f p (x:xs) = go [x] xs
where go acc [] = [acc]
go acc (y:ys) | p y = acc : go [y] ys
| otherwise = go (acc++[y]) ys
これにより、現在のサブリストが何であるかを常に記憶し、リストの末尾全体を再帰的に走査し、p
適用される要素に到達すると、現在のサブリストを出力して新しいサブリストを開始します。
最初の要素がすでに満たされ、空の最初のサブリストを出力したくない場合を提供する[x]
代わりに、 go first が受け取ることに注意してください。[]
p x
[1..7]
また、これは の代わりに元のリスト ( ) で動作し[[1],[2]...]
ます。ただし、変換されたものでも使用できます。
> map concat $ f (odd . head) [[1],[2],[3],[4],[5],[6],[7]]
[[1,2],[3,4],[5,6],[7]]
まず、リスト内包表記を使用できます。
>>> [[x] | x <- [1,2,3,4,5,6]]
[[1], [2], [3], [4], [5], [6]]
2 番目の問題については、パッケージによって提供されるData.List.Splitモジュールを使用できます。split
import Data.List.Split
f :: (a -> Bool) -> [[a]] -> [[a]]
f predicate = split (keepDelimsL $ whenElt predicate) . concat
の関数はリストのリストではなくリストで機能するため、この最初のconcatはリストを連結します。split
結果の単一リストは、分割パッケージの関数を使用して再度分割されます。