Вот несколько советов, которые помогут вам начать:
Создание строк вместо печати
Помимо функции printf
, которая печатает на экран, в F # есть функция sprintf
, которая работает так же, как printf
, но вместо этого возвращает строку. Например.,
let number = 2 + 3
printf "%i" number // Prints "5", does not return a value
let text = sprintf "%i" number // Assigns the string "5" to the variable "text"
Скобки иногда нужны
Одна часть синтаксиса F # может застать новичков врасплох: тот факт, что приложение функции имеет более высокий приоритет, чем операторы. Что это значит на практике? Ну, посмотрите на этот код:
let text = sprintf "Sum: %i" 2+3
Это должно вернуть "Sum: 5", верно? Нет: он выдаст вам ошибку компилятора, сообщающую, что вы не можете добавлять строки и целые числа. Это потому, что когда F # видит функцию, за которой следует любое количество параметров, он считает, что применение функции (применение параметров к функции) имеет более высокий приоритет , чем другие операторы. Другими словами, точно так же, как 2+3*4
рассматривается как 2+(3*4)
, потому что умножение имеет более высокий приоритет, чем сложение, приоритет этого примера кода работает так:
let text = sprintf "Sum: %i" 2+3
// is equivalent to
let text = (sprintf "Sum: %i" 2)+3
// but NOT equivalent to
let text = sprintf "Sum: %i" (2+3)
Таким образом, F # обрабатывает это как let text = (sprintf "Sum: %i" 2)+3
, которое становится let text = "2"+3
. В некоторых языках, таких как Javascript, это допустимо ... но ожидаете ли вы, что будет получена строка "5"? Или целое число 5? Или строка "23"? Это неоднозначно. Поэтому F # запрещает добавлять два разных типа (например, строки и целые числа) вместе, чтобы никогда не возникало двусмысленности относительно того, как следует интерпретировать любое выражение.
Теперь, если вы написали эту строку sprintf
в моем примере, то, что вы, вероятно, предполагали, был вариант (2+3)
. Так что, если вы используете sprintf
(или любую другую функцию) и одна из вещей, которую вы хотите передать, это вычисленное значение, тогда вам нужно заключить круглые скобки вокруг вычисленного значения. Это также относится к результатам вызовов функций:
let double x = x * 2
let text = sprintf "Result: %i" double 5 // Compiler error
let text = sprintf "Result: %i" (double 5) // Returns "Result: 10"
Заполнение строки пробелами или нулями
Если вы используете функции printf
или sprintf
для печати числа или преобразования числа в строку, вы можете указать ширину в коде формата %i
, например, так:
let shortString = sprintf "%i" 5 // Returns the string "5"
let longString = sprintf "%3i" 5 // Returns the string " 5"
let leftJustified = sprintf "%-3i" 5 // Returns the string "5 "
let zeroPadded = sprintf "%03i" 5 // Returns the string "005"
let tooLong = sprintf "%3i" 9999 // Returns the string "9999"
Как видите, символ -
перед шириной будет выравнивать число по левому краю, так что после пробела будет стоять после числа вместо до, а символ 0
перед шириной будет дополнять нулями вместо пробелов. Число никогда не будет усечено: если вы укажете ширину, которая слишком мала для используемого вами числа (например, в моем примере мы пытаемся вписать 9999 в ширину 3), полное число будет напечатано или возвращено в виде строки, которая может в результате получается строка, которая больше, чем вы ожидали.
Составление списка для циклов
F # также имеет функцию, называемую список пониманий . Если вы знакомы с Python, они работают немного похоже на понимание списка Python, но с другим синтаксисом (естественно). В частности, представления списка F # выглядят как обычный код F #, но вы используете ключевое слово yield
для помещения значений в список. Например.,
// A list of all the numbers from 1 to 10
let numbers = [
for i = 1 to 10 do
yield i
]
// A list of all the even numbers from 2 to 20
let evenNumbers = [
for i = 1 to 10 do
yield i * 2
]
// You can use nested for loops as well
let nestedLoops = [
for i = 1 to 10 do
for j = 1 to i do
yield i + j
]
Объединение списков
Теперь вы, возможно, уже выяснили, как можно объединить эти понятия, чтобы составить список строк, таких как [" 1"; " 2"; " 3"]
и так далее. Допустим, у вас есть два списка, каждый из которых представляет одну строку текста, которую вы хотите вернуть, - и скажем, что вы хотите объединить их с \n
(символом новой строки) между ними. Один из способов сделать это можно так:
let combined = list1 @ ["\n"] @ list2
Обратите внимание, что оператор @
означает «добавить два списка», поэтому элементы с обеих сторон @
должны быть списком. Выполнение list1 @ "\n" @ list2
не сработало бы, потому что строка "\n"
не является списком.
Но если ваш класс еще не охватил оператор добавления списка @
, то вы можете объединить два списка с помощью всего лишь for
циклов и оператора yield
:
let combined = [
for x in list1 do
yield x
yield "\n"
for x in list2 do
yield x
]
Это не лучший способ сделать это (есть оператор yield!
, который был бы лучше), но лучшие способы сделать это - более сложные предметы, которые ваш профессор может планировать освещать позже.Если вы хотите узнать о них, оставьте комментарий, и я объясню (или найду хорошее объяснение для ссылки).
Превращение списка строк в одну строку
ПоследнийЧасть головоломки заключается в том, как превратить список строк в одну строку.Для этого лучше всего использовать функцию String.concat
.Он принимает два параметра: первый - это строка, которая должна быть помещена между каждым элементом (и это может быть пустой строкой).Второй параметр - это список элементов для объединения.Пример:
String.concat "+" ["a"; "b"] // Returns "a+b"
String.concat "" [" 1"; " 2"; " 3"] // Returns " 1 2 3"
Вы можете взять его отсюда
Это должны быть все части, которые вам нужно собрать, чтобы написать функцию.Я намеренно использовал примеры, которые похожи на , что вам нужно, но не точно , что вам нужно.Теперь вам предстоит выяснить, как собрать кусочки головоломки и построить свою функцию.Удачи!