Преобразовать список символов (или массив) в строку - PullRequest
14 голосов
/ 28 февраля 2010

как преобразовать список символов в строку?

Другими словами, как изменить List.ofSeq "abcd"?

ОБНОВЛЕНИЕ: new System.String (List.ofSeq "abcd" |> List.toArray) |> printfn "%A", кажется, работает нормально, с new или без него, но List.ofSeq "abcd" |> List.toArray) |> new System.String |> printfn "%A" не удается. Почему?

Ответы [ 4 ]

23 голосов
/ 28 февраля 2010

Я задавал похожий вопрос один раз. Кажется, конструкторы объектов не могут быть компонованы, поэтому вы не можете передать их как функцию.

List.ofSeq "abcd" |> List.toArray |> (fun s -> System.String s) |> printfn "%A"
List.ofSeq "abcd" |> List.toArray |> (fun s -> new System.String(s)) |> printfn "%A"

Обновление Конструкторы являются первоклассными функциями с F # 4.0

List.ofSeq "abcd" |> List.toArray |> System.String |> printfn "%A"
13 голосов
/ 01 марта 2010

Работа со строками в F # иногда немного неудобна. Я бы, наверное, использовал тот же код, что и Дарио. Грамматика F # не позволяет использовать конструкторы в качестве функций первого класса, поэтому вы, к сожалению, не можете выполнить всю обработку в одном конвейере. В общем случае вы можете использовать статические члены и методы экземпляра в качестве функций первого класса, но не свойства или конструкторы экземпляра.

В любом случае, есть очень неприятный прием, который вы можете использовать, чтобы превратить конструктор в значение функции. Я бы не советовал на самом деле использовать его, но я был очень удивлен, увидев, что он действительно работает, поэтому я подумал, что стоит поделиться им:

let inline ctor< ^R, ^T 
  when ^R : (static member ``.ctor`` : ^T -> ^R)> (arg:^T) =
   (^R : (static member ``.ctor`` : ^T -> ^R) arg)

Это определяет функцию, которая будет встроена во время компиляции, которая требует, чтобы параметр первого типа имел конструктор, который принимает значение параметра второго типа. Это указывается как ограничение времени компиляции (потому что .NET generics не может это выразить). Кроме того, F # не позволяет вам указать это, используя обычный синтаксис для указания ограничений конструктора (который должен принимать unit в качестве аргумента), но вы можете использовать скомпилированное имя конструкторов. Теперь вы можете написать, например:

// just like 'new System.Random(10)'
let rnd = ctor<System.Random, _> 10
rnd.Next(10)

И вы также можете использовать результат ctor как первоклассную функцию:

let chars = [ 'a'; 'b'; 'c' ]
let str = chars |> Array.ofSeq |> ctor<System.String, _>

Как я уже сказал, я думаю, что это в основном любопытство, но довольно интересное :-).

5 голосов
/ 28 февраля 2010

Ваш подход:

new System.String (listOfChars |> List.toArray)

- это решение, с которым я обычно сталкиваюсь.

Система вывода грамматики / типа F # просто не может распознать конструктор .NET, такой как new String, как функцию с карри (что не позволяет использовать конвейерную обработку).

1 голос
/ 03 февраля 2012

Просто столкнулся с подобной проблемой, и придумал это решение:

List.fold (fun str x -> str + x.ToString()) "" (List.ofSeq "abcd") 
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...