Есть ли какая-нибудь функция haskell для объединения списка с разделителем?

Есть ли функция для объединения элементов списка с разделителем? Например:

> foobar " " ["is","there","such","a","function","?"]
["is there such a function ?"]

Спасибо за любой ответ!


person Fopa Léon Constantin    schedule 10.02.2012    source источник
comment
Я знаю, что lmgtfy плохие ответы, но стоит отметить, что поиск String - ›[String] -› String на hoogle дает именно то, что вы хотите. haskell.org/hoogle   -  person sigfpe    schedule 10.02.2012
comment
для соединения с пробелами у вас также есть unwords   -  person epsilonhalbe    schedule 10.02.2012
comment
@sigfpe Боковой комментарий: вам нужно будет искать [String] -> String -> String в случае, если другой способ не вернет ответа, верно?   -  person Lay González    schedule 09.03.2014
comment
@ LayGonzález Поиск до перестановок. Например, поиск _ 1_ возвращает map в качестве первого результата.   -  person gallais    schedule 19.06.2016


Ответы (4)


Да, есть:

Prelude> import Data.List
Prelude Data.List> intercalate " " ["is","there","such","a","function","?"]
"is there such a function ?"

intersperse немного больше Общее:

Prelude> import Data.List
Prelude Data.List> concat (intersperse " " ["is","there","such","a","function","?"])
"is there such a function ?"

Кроме того, для конкретного случая, когда вы хотите присоединиться с пробелом, существует _ 4_:

Prelude> unwords ["is","there","such","a","function","?"]
"is there such a function ?"

unlines работает аналогично, только что строки складываются с использованием символа новой строки и что символ новой строки также добавляется в конец. (Это делает его полезным для сериализации текстовых файлов, которые в соответствии со стандартом POSIX должны заканчиваться новой строкой в ​​конце)

person Niklas B.    schedule 10.02.2012
comment
Может ли что-нибудь из этого иметь дело с возможными пустыми строками? - person CMCDragonkai; 23.06.2015
comment
@CMCDragonkai Не уверен, что именно вы имеете в виду, но да, все эти функции позволяют использовать произвольные строки как в качестве разделителя, так и в качестве элементов. Например, intercalate "," ["some", "", "string"] = "some,,string" и intercalate "" ["foo", "bar"] = "foobar" - person Niklas B.; 23.06.2015
comment
unlines добавляет новую строку к каждой строке, то есть unlines ["A", "B"] = "A\nB\n", поэтому это не то же самое, что и вставка. - person Kathy Van Stone; 27.04.2017
comment
@KathyVanStone Интересно, наверное, я никогда не пробовал и только предполагал, что он работает аналогично unwords. - person Niklas B.; 27.04.2017
comment
Приятно, что в стандартной библиотеке есть несколько обычных функций управления строками и списками, и приятно, что вы публикуете здесь пример, потому что довольно сложно найти какую-либо документацию для такого рода повседневного программирования в Haskell. - person Andrew Koster; 02.07.2020

Нетрудно написать однострочник с помощью foldr

join sep xs = foldr (\a b-> a ++ if b=="" then b else sep ++ b) "" xs
join " " ["is","there","such","a","function","?"]
person Ilya Kharlamov    schedule 21.05.2017
comment
Было бы полезно добавить к этому описание; кто-то отметил его как низкое качество. - person Arya McCarthy; 22.05.2017

Еще несколько идей реализации вкраплений и вставок, если кому-то интересно:

myIntersperse :: a -> [a] -> [a]
myIntersperse _ [] = []
myIntersperse e xs = init $ xs >>= (:[e])

myIntercalate :: [a] -> [[a]] -> [a]
myIntercalate e xs = concat $ myIntersperse e xs

xs >>= f эквивалентно concat (map f xs).

person Alexis    schedule 08.02.2020

Если вы хотите написать свои собственные версии intercalate и 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)
person Zoey Hewll    schedule 04.02.2017
comment
Зачем ограничиваться струнами? Кроме того, ваши пары вокруг приложения функции избыточны. - person melpomene; 04.02.2017
comment
Верно, intersperse не обязательно должно быть Strings, но intercalate должно быть по крайней мере Show, и если вы действительно использовали Show, вам все равно понадобится какой-то способ справиться с ними, используя Strings. Я все еще привыкаю к ​​тому, как Haskell имеет дело со смешанными инфиксными и префиксными функциями / операторами, и я предпочитаю использовать скобки при микшировании на случай, если я захочу использовать $ - person Zoey Hewll; 04.02.2017
comment
intercalate :: [a] -> [[a]] -> [a] - почему Show? Что касается синтаксиса, то в Haskell нет никаких префиксных операторов (кроме -, что является мерзостью), а приложение-функция связывает сильнее, чем любой инфиксный оператор: x:s:intersperse s xs это нормально (но он читается намного лучше, если вы вставите пробелы в: x : s : intersperse s xs (Я действительно не понимаю, почему людям нравится оставлять пробелы вокруг :)). - person melpomene; 04.02.2017
comment
Правильно. Я все время забываю, что работа со строками - это просто работа со списками. Show было потому, что я предполагал, что вы хотите, чтобы результат был String. Под инфиксными и префиксными функциями / операторами я имел в виду префиксные функции и инфиксные операторы, но это было неясно. Унарный - - это смерть. Что касается :s и других инфиксных операторов, то, использую ли я пробелы, сильно зависит от контекста, но я всегда локально согласован. например, (:) в сопоставлении с шаблоном никогда не имеет пробелов, но в другом месте это зависит от того, заключено ли оно в квадратные скобки, и от моего настроения. - person Zoey Hewll; 04.02.2017