リストのリスト ([[a]]) を返すが、空のリスト ([]:[a]) を使用しない場合の構文は (可能な場合) でしょうか? (下の 2 番目にコメントされたガード (2) に似ていますが、これは正しくありません)
これは正しく動作する関数です:
-- Split string on every (shouldSplit == true)
splitWith :: (Char -> Bool) -> [Char] -> [[Char]]
splitWith shouldSplit list = filter (not.null) -- would like to get rid of filter
(imp' shouldSplit list)
where
imp' _ [] = [[]]
imp' shouldSplit (x:xs)
| shouldSplit x = []:imp' shouldSplit xs -- (1) this line is adding empty lists
-- | shouldSplit x = [imp' shouldSplit xs] -- (2) if this would be correct, no filter needed
| otherwise = let (z:zs) = imp' shouldSplit xs in (x:z):zs
これが正しい結果です
Prelude> splitWith (== 'a') "miraaaakojajeja234"
["mir","koj","jej","234"]
ただし、結果をクリーンアップするには「フィルター」を使用する必要があるため、関数「フィルター」を削除したいと考えています。これは、フィルターを使用しない場合の結果です。
["mir","","","","koj","jej","234"]
最初のガードの代わりに" | shouldSplit x = imp' shouldSplit xs " を使用すると、結果は正しくありません。
["mirkojjej234"]
最初のガード (1) は空のリストを追加するため、コンパイラは結果をリストのリスト ([[a]]) として扱うことができると思います。
(関数の別の/異なるソリューションには興味がありません。構文の明確化だけです。)
.
.
.
答え:
Dave4420 からの回答で回答が得られましたが、回答ではなくコメントだったので、回答として受け入れることはできません。問題の解決策は、私が間違った質問をしているということでした。これは構文の問題ではなく、私のアルゴリズムの問題です。
空のリストの問題を解決する別の/異なるソリューションにはいくつかの回答がありますが、それらは私の質問に対する回答ではありません。しかし、彼らは、基本的な Haskell 構文を使って物事を行う方法について、私の見解を広げてくれました。私は彼らに感謝しています。
編集:
splitWith :: (Char -> Bool) -> String -> [String]
splitWith p = go False
where
go _ [] = [[]]
go lastEmpty (x:xs)
| p x = if lastEmpty then go True xs else []:go True xs
| otherwise = let (z:zs) = go False xs in (x:z):zs