Быстрый вопрос, который может быть более напыщенным (но я надеюсь, что я просвещен).
В F # строка совместима с Seq так, что "abcd" | > Seq.map f будет работать с строкой.
Это блестящее средство для работы со строками, например, чтобы взять первые 5 символов из строки:
"abcdef01234567" |> Seq.take 5
Или удаление повторяющихся символов:
"abcdeeeeeee" |> Seq.distinct
Проблема заключается в том, что после получения результата char seq становится крайне неудобно снова преобразовывать это обратно в строку, String.concat "" требует, чтобы члены были строками, поэтому я в конечном итоге делаю это много
"abcdef01234567"
|> Seq.take 5
|> Seq.map string
|> String.concat ""
Настолько, что у меня есть функция, которую я использую в 90% моих проектов:
let toString : char seq -> string = Seq.map string >> String.concat ""
Я чувствую, что это сверху, но везде я ищу, чтобы найти альтернативу. Меня встречают такие отвратительные вещи, как StringBuilder или встраивание лямбды и использование нового:
"abcdef01234567"
|> Seq.take 5
|> Seq.toArray
|> fun cs -> new string (cs) (* note you cannot just |> string *)
Мое (возможно, сумасшедшее) ожидание, которое я хотел бы видеть на этом языке, заключается в том, что когда Seq используется в строке, сигнатура типа из результирующего выражения должна быть строкой → строкой. Смысл, что происходит, это то, что выходит. "abcd" | > Seq.take 3 = "abc".
Есть ли причина, по которой мои ожидания от строковой манипуляции высокого уровня ошибочны в этом случае?
Есть ли у кого-нибудь рекомендация по подходящему подходу к этому, я чувствую, что мне что-то не хватает.