Для этого требуется распаковка.
Во-первых, Ваша основная ошибка: System.Char.ToUpper
- это функция. Он принимает символ и возвращает другой символ. Это не так "update" его аргумент к новому значению.
let x = 'a'
let y = System.Char.ToUpper x // y = 'A', x = 'a'.
В приведенном выше коде, я даю имя y
к результату функции. Значение y
составляет 'A'
, но значение x
по-прежнему 'a'
. После вызова функции x
не изменился.
С этой целью следует следующее.
Второй, List.iter
- это функция, которая для каждого элемента списка заставляет что-то «случиться». Это не заменить каждый элемент списка с чем-то новым, и он не создает новый список. Он просто делает что-то происходит для каждого элемента. Простейшим примером такой «то» печатает к консоли:
List.iter (fun x -> printfn "%i" x) [1; 2; 3] // Prints "1", then "2", then "3"
Обратите внимание, что эта функция принимает два аргумента: функцию, которая представляет что-то, что должно произойти, и список, из которого в взять элементы. В вашем вопросе вам, кажется, не хватает второго аргумента. Как мог бы List.iter
узнать, какой список использовать?
Первый аргумент List.iter
должен быть функцией, которая возвращает unit
. Это особый тип в F #, который в основном означает «no value». Когда функция не возвращает значение, это означает, что единственная причина для его вызова заключалась в том, чтобы сделать что-то внешнее произошло (известно в функциональном программировании как «побочный эффект»). Вот почему List.iter
требует, чтобы функция возвращала unit
- это дополнительная защита от случайной подачи неправильной функции, как и вы, на самом деле: функция, которую вы предоставили, возвращает char
. Вот почему вы получаете полученную вами ошибку.
Третий, так же, как с ToUpper
, называя List.ofArray
не каким-то образом «обновление» x
быть списком.Вместо этого он возвращает список. Если вы не дадите этому возвращенному списку имя, оно просто будет потеряно. Это означает, что способ, которым вы звоните List.ofArray
, бесполезен.
Что вам нужно - (1) принять последовательность символов в вашей строке, затем (2) преобразовать ее в новую последовательность, где каждый символ является верхним регистром, затем (3) склеить эти символы вместе для получения новой строки.
Шаг (1) - это не-op, потому что строки .NET - это уже последовательности символов (т. Е. Они реализуют IEnumerable<char>
). Этап (2) выполняется посредством общей операции, называемой Seq.map
. Это операция, которая преобразует последовательность в новую последовательность, применяя данную функцию к каждому элементу. «Данная функция» в этом случае будет System.Char.ToUpper
. Шаг (3) может быть выполнен с помощью String.concat
, но вам нужно сначала преобразовать каждый символ в строку, потому что String.concat
берет последовательность строк, а не символов.
let chars = s
let upperChars = Seq.map System.Char.ToUpper chars
let strChars = Seq.map string upperChars
let result = String.concat "" strChars
Или это может быть сделано в течение более короткого пути, не давая результата каждого шага в отдельное имя, но по конвейеру каждый результат прямо в следующей операции:
let result =
s
|> Seq.map System.Char.ToUpper
|> Seq.map string
|> String.concat ""
И наконец, там на самом деле гораздо более короткий способ сделать это, но это настолько смехотворно очевидно, что это похоже на обман.
Дело в том, что строки являются последовательностями, для них имеет смысл иметь все операции последовательности. И угадай что? Они делают! В частности, имеется функция String.map
, которая делает то же самое, как Seq.map
, но для строк:
let result = String.map System.Char.ToUpper s
Благодарим Вас за время, чтобы объяснить все, что мне. Я абсолютно не знаком с f #, поскольку, я уверен, вы могли бы сказать. – jynx678
Если вы новичок, вот отличный ресурс для запуска: https://fsharpforfunandprofit.com/ –