Wiem, że odpowiedzi lmgtfy są złe, ale warto zauważyć, że wyszukiwanie „String -> [String] -> String” w hoogle daje dokładnie to, czego chcesz. haskell.org/hoogle
sigfpe
3
do łączenia ze spacjami, które również maszunwords
epsilonhalbe
1
@sigfpe Komentarz boczny: Musiałbyś poszukać na [String] -> String -> Stringwypadek, gdyby w drugą stronę brakowało odpowiedzi, prawda?
Lay González
1
@ LayGonzález Wyszukiwanie zależy od permutacji. Na przykład wyszukiwanie [a] -> (a -> b) -> [b]zwrotów mapjako pierwszego wyniku.
Prelude> import Data.List
PreludeData.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)
Czy którykolwiek z nich może poradzić sobie z możliwymi pustymi ciągami?
CMCDragonkai
3
@CMCDragonkai Nie jestem pewien, do czego dokładnie się odnosisz, ale tak, wszystkie te funkcje pozwalają na użycie dowolnych ciągów znaków jako separatora i elementów. Na przykład intercalate "," ["some", "", "string"] = "some,,string"iintercalate "" ["foo", "bar"] = "foobar"
Niklas B.
3
unlinesdodaje nową linię do każdej linii, to znaczy unlines ["A", "B"] = "A\nB\n", że nie jest tym samym, co interkalacja.
Kathy Van Stone
@KathyVanStone Interesujące, chyba nigdy nie próbowałem i tylko założyłem, że działa to analogicznie do unwords.
Niklas B.
1
Fajnie, że w standardowej bibliotece są jakieś normalne funkcje do manipulacji na ciągach znaków i listach, i fajnie, że publikujesz tutaj przykład, ponieważ dość trudno jest znaleźć jakąkolwiek dokumentację do tego rodzaju codziennego programowania w Haskell.
Andrew Koster
4
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","?"]
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)
Po co ograniczać się do strun? Ponadto parens wokół aplikacji funkcji są zbędne.
melpomene
To prawda, że 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ę $
nawiasy kwadratowe
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ół :)).
melpomene
Dobrze. Ciągle zapominam, że praca z napisami to tylko praca z listami. 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.
unwords
[String] -> String -> String
wypadek, gdyby w drugą stronę brakowało odpowiedzi, prawda?[a] -> (a -> b) -> [b]
zwrotówmap
jako 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 ?"
unlines
dział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)źródło
intercalate "," ["some", "", "string"] = "some,,string"
iintercalate "" ["foo", "bar"] = "foobar"
unlines
dodaje nową linię do każdej linii, to znaczyunlines ["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","?"]
źródło
joinBy sep cont = drop (length sep) $ concat $ map (\w -> sep ++ w) cont
źródło
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 >>= f
jest równoważneconcat (map f xs)
.źródło
Jeśli chcesz napisać własne wersje
intercalate
iintersperse
: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)
źródło
intersperse
nie musi tak byćStrings
, aleintercalate
musiałby być co najmniejShow
, a jeśli tak używaniaShow
, którą trzeba w jakiś sposób radzić sobie z nimi za pomocąString
e 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]
- dlaczegoShow
? 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 xs
jest 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ół:
)).Show
wynikał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.