Подтвердить что ты не робот

F #: оператор String.Join и |>

В F # interactive я могу успешно использовать String.Join("+", ["a"; "b"]), но

["a"; "b"] |> String.Join "+"

создает ошибку:

Script1.fsx(79,15): error FS0001: This expression was expected to have type
    string list -> 'a    
but here has type
    string

Как использовать String.Join передачу коллекции по конвейеру?

P.S. Эта же проблема связана с lines |> File.WriteAllLines "filename.txt"

4b9b3361

Ответ 1

String.Join - это метод .NET. При использовании метода .NET F # рассматривает его как функцию, которая принимает кортеж в качестве аргумента (при вызове он записывает параметры как f(a, b)). Оператор |> может использоваться с функциями, использующими карри-форму параметров (и может быть вызван путем записи f a b).

Вместо этого вы можете использовать функцию String.concat из библиотеки F # (которая делает то же самое):

["a"; "b"] |> String.concat "+"

EDIT File.WriteAllLines - это тот же случай. Если вы хотите использовать его как часть конвейера, вы можете написать функцию F #, которая завершает вызов:

let writeAllLines file (lines:seq<string>) =
  System.IO.File.WriteAllLines(file, lines)

В общем, вы можете использовать |> с методами .NET, только если вы хотите написать все аргументы в левой части оператора. Вы можете, например, написать:

("+", ["a"; "b"]) |> System.String.Join

... но это не соответствует обычному использованию оператора трубопровода. При работе с .NET API обычно лучше использовать С# -подобный стиль программирования (без конвейерной обработки), потому что трубопровод работает только с функциональными библиотеками.

Ответ 2

Я думал, что буду взвешивать альтернативу. OP специально задал вопрос о String.Join, а Tomas Petricek ответил абсолютно правильно для этого метода (используйте String.concat из библиотеки F #).

Если вы говорите о другом методе, который принимает аргументы, но вы хотите использовать их как curried, вы можете использовать эту вспомогательную функцию:

let partial f x y = f(x, y)

Это позволяет вам передать метод "частичным" и вернуть функцию карри. Используйте его так:

let partial f x y = f(x, y)
myCollection |> partial String.Join "&"