2

「分割統治」を使用せずに 2 つのリストを結合する関数を作成しようとしています。したがって、私は使用できません(++)

Prelude> let combineList (x:xs) (y:ys) = if null (y:ys)==True then x:xs else combineList (x:xs++[y]) (ys)

これは私が今持っているもので、"Non-exhaustive patterns in function combineList". if null (y:ys)==Trueこの機能が機能するため、問題が から発生していることに気付きました-

Prelude> let combineList (x:xs) (y:ys) = if ys==[] then x:xs++[y] else combineList (x:xs++[y]) (ys)

++[y]しかし、可能であれば、出力の を取り除きたいです。

コードの修正は大歓迎です。

4

2 に答える 2

3

(x:xs)どのリストとも一致しません。xむしろ、head 要素と tailを持つリストに一致しますxs(コンスセルに一致するものと考えることができると思います。)基本的に定義により、null (x:xs)any は null ではないため、false になることはありません。(x:xs)

"Non-exhaustive patterns in function"入力が関数のパターンに一致しなかったことを意味します。この場合、どちらの引数も null にすることはできないため、どちらかが null の場合、一致エラーが発生します。

どうやら s でやっているようなので、任意のリストifに一致させたいので、関数は次のようになります

combineList xs ys = if null xs then ys else head xs : combineList (tail xs) ys

ただし、haskell でこれを行うより一般的な方法は、nilパターンに対して個別にパターン マッチを行うことです。

cl [] ys = ys
cl (x:xs) ys = x : cl xs ys

(これは の定義と同等です(++)が、接頭辞形式です:)

(++) :: [a] -> [a] -> [a]
(++) []     ys = ys
(++) (x:xs) ys = x : xs ++ ys
 -- or         = x : (++) xs ys

また、折り畳みパターンに従います。最初のテールとして使用される 2 番目のリストを使用して、最初のリストにコンシングを累積できます。

cl' xs ys = foldr (:) ys xs

これにより、関数を無意味に (つまり、無意味なスタイルで) 書くこともでき

cl'' = flip (foldr (:))
于 2013-10-01T01:13:00.680 に答える
1

警告は、関数がdata type"Non-exhaustive patterns in function `combineList`"のすべてのコンストラクターと一致するパターンではないことを意味します。type には 2 つのコンストラクターと;が含まれます。パターン マッチングを使用する場合、コンパイラは、データ型のすべてのコンストラクターを一致させる必要があると想定します。List(:)[]

考えられる解決策の 1 つを次に示します。

combineList (x:xs) ys = if null xs then x : ys else x : combineList xs ys

Haskell でこれを記述するより良い方法は、パターン マッチングを使用することです。これは の実際の定義でもあることに注意してください(++)

combineList []     ys = ys 
combineList (x:xs) ys = x : combineList xs ys
于 2013-10-01T01:04:43.957 に答える