Czy istnieje funkcja konkatenacji elementów listy z separatorem? Na przykład:
> foobar " " ["is","there","such","a","function","?"]
["is there such a function ?"]
Dzięki za każdą odpowiedź!
Czy istnieje funkcja konkatenacji elementów listy z separatorem? Na przykład:
> foobar " " ["is","there","such","a","function","?"]
["is there such a function ?"]
Dzięki za każdą odpowiedź!
unwords
[String] -> String -> Stringwypadek, gdyby w drugą stronę brakowało odpowiedzi, prawda?
[a] -> (a -> b) -> [b]zwrotów mapjako pierwszego wyniku.
Odpowiedzi:
Tak, jest :
Prelude> import Data.List
Prelude Data.List> intercalate " " ["is","there","such","a","function","?"]
"is there such a function ?"
intersperse jest nieco bardziej ogólny:
Prelude> import Data.List
Prelude Data.List> concat (intersperse " " ["is","there","such","a","function","?"])
"is there such a function ?"
Ponadto w konkretnym przypadku, w którym chcesz połączyć znak spacji, jest unwords:
Prelude> unwords ["is","there","such","a","function","?"]
"is there such a function ?"
unlinesdziała podobnie, tylko że ciągi są implodowane przy użyciu znaku nowej linii i że znak nowej linii jest również dodawany na końcu. (To sprawia, że jest to przydatne do serializacji plików tekstowych, które zgodnie ze standardem POSIX muszą kończyć się końcowym znakiem nowej linii)
intercalate "," ["some", "", "string"] = "some,,string"iintercalate "" ["foo", "bar"] = "foobar"
unlinesdodaje nową linię do każdej linii, to znaczy unlines ["A", "B"] = "A\nB\n", że nie jest tym samym, co interkalacja.
unwords.
Nie jest trudno napisać jedną linijkę za pomocą foldr
join sep xs = foldr (\a b-> a ++ if b=="" then b else sep ++ b) "" xs
join " " ["is","there","such","a","function","?"]
Kilka innych pomysłów na implementacje intersperse i interkalate, jeśli ktoś jest zainteresowany:
myIntersperse :: a -> [a] -> [a]
myIntersperse _ [] = []
myIntersperse e xs = init $ xs >>= (:[e])
myIntercalate :: [a] -> [[a]] -> [a]
myIntercalate e xs = concat $ myIntersperse e xs
xs >>= fjest równoważne concat (map f xs).
Jeśli chcesz napisać własne wersje intercalatei intersperse:
intercalate :: [a] -> [[a]] -> [a]
intercalate s [] = []
intercalate s [x] = x
intercalate s (x:xs) = x ++ s ++ (intercalate s xs)
intersperse :: a -> [a] -> [a]
intersperse s [] = []
intersperse s [x] = [x]
intersperse s (x:xs) = x : s : (intersperse s xs)
interspersenie musi tak być Strings, ale intercalatemusiałby być co najmniej Show, a jeśli tak używania Show, którą trzeba w jakiś sposób radzić sobie z nimi za pomocą Stringe tak. Nadal przyzwyczajam się do tego, jak Haskell radzi sobie z mieszanymi funkcjami / operatorami wrostków i prefiksów, i wolę $
intercalate :: [a] -> [[a]] -> [a]- dlaczego Show? Jeśli chodzi o składnię, Haskell nie ma żadnych operatorów prefiksów (poza tym -, co jest obrzydliwością), a aplikacja funkcji wiąże mocniej niż jakikolwiek operator wrostka: x:s:intersperse s xsjest w porządku (ale czyta znacznie lepiej, jeśli umieścisz spacje w: x : s : intersperse s xs(nie naprawdę nie rozumiem, dlaczego ludzie lubią pomijać przestrzenie wokół :)).
Showwynikało z tego, że zakładałem, że chcesz, aby wynik był String. Przez „funkcje / operatory przedrostków” miałem na myśli „funkcje przedrostkowe i operatory wrostkowe”, ale to było niejasne. Jednoargumentowe -to śmierć. Jeśli chodzi o :s i inne operatory infix, to, czy używam spacji, zależy w dużym stopniu od kontekstu, ale zawsze jestem lokalnie spójny. np. (:)w dopasowaniu wzorca nigdy nie ma spacji, ale gdzie indziej zależy to od tego, czy jest w nawiasach i od mojego nastroju.