#f# #formatting #visual-studio-2019
#f# #форматирование #visual-studio-2019
Вопрос:
Q1: Я хочу отформатировать функцию F # по нескольким строкам в * .fsx в Visual Studio 2019, но когда я пытаюсь, я получаю синтаксические ошибки. (См. Ниже.)
Q2: В Haskell (насколько я помню) порядок, в котором вы объявляете функции, не имеет значения. Верно ли то же самое в F #?
(*
2.3 Declare the F# function
isIthChar: string * int * char -> bool
where the value of isIthChar(str,i,ch) is true
if and only if ch is the i’th character in the string str
(numbering starting at zero).
Hansen, Michael R.. Functional Programming Using F# (p. 39). Cambridge University Press. Kindle Edition. *)
let isIthChar (str: string, i, ch) = (ch = str.[i])
(*
2.4 Declare the F# function
occFromIth: string * int * char -> int where
occFromIth(str, i, ch) =
the number of occurances of character ch
in positions j in the string str
with j >= i
Hint: the value should be 0 for i ≥ size str.
Hansen, Michael R.. Functional Programming Using F# (p. 39). Cambridge University Press. Kindle Edition.
*)
let rec countChar(str, i, j, ch, cnt) = if j < i then cnt else if isIthChar(str, j, ch) then countChar(str, i, j - 1, ch, cnt 1) else countChar(str, i, j - 1, ch, cnt);; // all one line
let occFromIth(str, i, ch) = if (i >= String.length str) then 0 else countChar(str, i, (String.length str) - 1, ch, 0);; // all one line
//WANT something like:
let rec countChar(str, i, j, ch, cnt) = if j < i
then cnt
else if isIthChar(str, j, ch)
then countChar(str, i, j - 1, ch, cnt 1)
else countChar(str, i, j - 1, ch, cnt);;
let occFromIth(str, i, ch) = if (i >= String.length str)
then 0
else countChar(str, i, (String.length str) - 1, ch, 0);;
// but these give syntax errors.
(* 2.5 Declare the F# function occInString: string * char -> int where
occInString(str, ch) = the number of occurences of a character ch in the string str.
Hansen, Michael R.. Functional Programming Using F# (p. 39). Cambridge University Press. Kindle Edition. *)
let occInString(str, ch) = occFromIth(str, 0, ch)
Ответ №1:
Форматирование: then
и else
должно быть как минимум таким же правым, как и их предыдущее if
, но в обоих ваших случаях они находятся слева от него. Просто переместите if
на следующую строку:
let rec countChar(str, i, j, ch, cnt) =
if j < i
then cnt
else if isIthChar(str, j, ch)
then countChar(str, i, j - 1, ch, cnt 1)
else countChar(str, i, j - 1, ch, cnt)
Также обратите внимание, что двойная точка с запятой не требуется, если код находится в fsx
файле, а не вводится в FSI с клавиатуры.
Порядок объявления: в отличие от Haskell, в F # все имена должны быть определены до их использования, поэтому ваша программа читается сверху вниз. На первый взгляд это может показаться ограничивающим, но на практике это творит чудеса с удобочитаемостью кода.
Исключением из этого правила является группа взаимно рекурсивных функций (или типов):
let rec f x = g (x 1)
and g x = f (x-1)
В этом примере g
используется до его определения.
Недавно в F # также появились рекурсивные модули, внутри которых все определения считаются одной большой рекурсивной группой:
module rec A =
let f x = g (x 1)
let g x = f (x-1)
Несколько замечаний, не связанных строго с вашими вопросами:
else if
может быть сокращеноelif
- Хотя параметры можно определить как кортеж
countChar(str, i, j, ch, cnt)
, обычно (и на практике гораздо удобнее) определять их в сокращенной формеcountChar str i j ch cnt
Комментарии:
1. Спасибо! Ваш ответ был ОЧЕНЬ полезен.