Reputation: 61
Q1: I want to format an F# function over multiple lines in *.fsx in Visual Studio 2019, but when I try, I get syntax errors. (See below.)
Q2: In Haskell (as I recall) the order in which you declare functions doesn't matter. Is the same true in 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)
Upvotes: 2
Views: 408
Reputation: 80744
Formatting: then
and else
must be at least as far to the right as their preceding if
, but in both your cases they're way to the left of it. Just move the if
on the next line:
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)
Also note that double-semicolon is not necessary if the code is in an fsx
file as opposed to being typed into FSI from keyboard.
Order of declaration: unlike Haskell, in F# all names must be defined before they're used, so your program reads top to bottom. This may seem limiting at first, but in practice it does wonders for code readability.
An exception to this rule is a group of mutually recursive functions (or types):
let rec f x = g (x+1)
and g x = f (x-1)
In this example g
is used before it's defined.
Recently F# also got recursive modules, inside which all definitions are considered to be one large recursive group:
module rec A =
let f x = g (x+1)
let g x = f (x-1)
A few notes not strictly related to your questions:
else if
can be abbreviated elif
countChar(str, i, j, ch, cnt)
, it is customary (and vastly more convenient in practice) to define them in curried form countChar str i j ch cnt
Upvotes: 2