Conversion from bool to int (true -> 1 and false -> 0) - f#

Is there any built-in way in F# to convert from true to 1 and false to 0? This is simple in languages like C, C++ etc.
As a bit of background I am trying to solve an exercise in a textbook (exercise 2.4 in Functional Programming Using F#), which asks for an F# function occFromIth(str,i,ch) that returns the number of occurrences of character ch in positions j in the string str with j >= i.
My solution is
let rec occFromIth (str : string, i, ch) =
if i >= str.Length then 0
else if i < 0 || str.[i] <> ch then occFromIth(str, i+1, ch)
else 1 + occFromIth(str, i+1, ch)
but I don't like the code duplication so I wrote
let boolToInt = function
| true -> 1
| false -> 0
let rec occFromIth (str : string, i, ch) =
if i >= str.Length then 0
else boolToInt (not (i < 0 || str.[i] <> ch)) + occFromIth(str, i+1, ch)
I guess another alternative is to use if... then... else..., in the style of the C/C++ conditional operator
let rec occFromIth (str : string, i, ch) =
if i >= str.Length then 0
else (if (not (i < 0 || str.[i] <> ch)) then 1 else 0) + occFromIth(str, i+1, ch)
or
let rec occFromIth (str : string, i, ch) =
if i >= str.Length then 0
else (if (i < 0 || str.[i] <> ch) then 0 else 1) + occFromIth(str, i+1, ch)
What is the way to do this in F#?

System.Convert.ToInt32(bool) -- I'm not too familiar with F#, but I believe that using a function is the same whether it is built in or not: function(arg0, arg1, ...). So, in this case you'd simply call System.Convert.ToInt32(myBool).

You don't really need the bool to int or int to bool as you can achieve the result as:
let occFromIth (str : string, i, ch) =
str
|> Seq.mapi (fun j c -> (j,c))
|> Seq.filter (fun (j,c) -> j >= i && c = ch)
|> Seq.length

There is difference in making a function or using build in. The CPU instruction of any comparison return a result translated to the bit pattern for 1 and 0. This can be used to make branchless programming, which dependend on the situation are more effecient then branching. Comparison of to values can be found without branching
Int min(int a, int b) {
Int temp = a < b;
Return a*temp + b*(1-temp);
}

Related

How to format a multi-line F# function in VisualStudio *.fsx

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)
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
While it's possible to define parameters as a tuple 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

Using methods inside loop invariants in Dafny

I'm trying to prove the simple gcd algorithm in Dafny, so I wrote the following, but it seems I can not use the method divides inside the loop invariants:
method divides(d: int, x: int) returns (result: bool)
requires d > 0
requires x > 0
ensures (result == true ) ==> (exists q : int :: (d * q == x))
ensures (result == false) ==> (forall q : int :: (d * q != x))
{
// code omitted
}
method gcd(a: int, b: int) returns (result: int)
requires a > 0
requires b > 0
ensures (forall d : int :: ((exists q1 : int :: q1 * d == a) && (exists q2 :: (q2 * d == b))) ==>
(exists q3 : int :: (q3 * d == result)))
{
var x := a;
var y := b;
var fuel := a+b;
while ((x != y) && (fuel > 0))
decreases fuel
invariant x > 0
invariant y > 0
invariant (forall d : int :: (divides(d,x) && divides(d,y)) ==> (divides(d,a) && divides(d,b)))
{
// code omitted
}
return x;
}
Is there anyway to use a divides method/function/macro inside invariants?
Unlike methods, functions can appear in expressions. You can create a function:
function div(d: int, x: int): bool
{
if (d != 0 && x % d == 0) then true else false
}
Then in your method divides, you can have
ensures result == div(d,x)
and in your method gcd you can use the function div in your invariant.
Note, from the Dafny guide: One caveat of functions is that not only can they appear in annotations, they can only appear in annotations. Functions are never part of the final compiled program, they are just tools to help us verify our code.

F# return from loop

I have the following piece of C++ code that I am trying to implement in F#. I get an error message with F# segment (the line between the if statement). As I understand it, the statement "i" applies not to the function but to the "for" loop?
C++ code
int move( Board b )
{
for( int i = 0; i < b.size(); ++i )
if( b(i) != "*" )
return i;
return -1;
}
F# code
let move (board:array<string>) :int =
for i = 0 to (board.Length-1) do
if( Array.item(i) board <> "*" ) then
i
done
-1
You can't break a loop in F#, but don't worry, when you're used to F# you won't need to, it's actually easier:
let move (board:array<string>) :int =
match Array.tryFindIndex (fun e -> e <> "*") board with
| Some n -> n
| None -> -1

Pure pattern matching

I am building a function that counts of many times a character appears in a string after the nth position.
countCh ("aaabbbccc", 3, 'b')
val it: int = 2
In C, I would use an accumulator with a while loop. But I am trying to learn the F# functional face, where this approach is discouraged.
So I used guards to test few conditions and build the function:
let rec countCh (s:string, n:int, ch:char) =
match s, n, ch with
| (s, n, ch) when n > s.Length -> 0 //p1
| (s, n, ch) when n < 0 -> 0 //p2
| (s, n, ch) when s.[n] <> ch -> countCh(s, n + 1, ch) //p3
| (s, n, ch) when s.[n] = ch -> 1 + countCh(s, n + 1, ch) //p4
The coexistence of patterns 3 and 4 is problematic (impossible, I am afraid). Even if it compiles, I have not been able to make it work. How can this task functionally be handled?
First, the coexistence of these branches is not problematic. They don't conflict with each other. Why do you think that it's problematic? Is it because you get an "Incomplete pattern match" compiler warning? That warning does not tell you that the branches conflict, it tells you that the compiler can't prove that the four branches cover all possibilities. Or do you think that for some other reason? If you want your questions to be answered accurately, you'll have to ask them more clearly.
Second, you're abusing the pattern matching. Look: there are no patterns! The patterns in every branch are exactly the same, and trivial. Only guards are different. This looks very counterintuitively within a match, but would be plainly expressed with if..elif:
let rec countCh (s:string) n ch =
if n >= s.Length || n < 0 then 0
elif s.[n] = ch then 1 + countCh s (n + 1) ch
else countCh s (n + 1) ch
NOTE 1: see how I made the parameters curried? Always use curried form, unless there is a very strong reason to use tupled. Curried parameters are much more convenient to use on the caller side.
NOTE 2: your condition n > s.Length was incorrect: string indices go from 0 to s.Length-1, so the bail condition should be n >= s.Length. It is corrected in my code.
Finally, since this is an exercise, I must point out that the recursion is not tail recursion. Look at the second branch (in my code): it calls the function recursively and then adds one to the result. Since you have to do something with the result of the recursive call, the recursion can't be "tail". This means you risk stack overflow on very long inputs.
To make this into tail recursion, you need to turn the function "inside out", so to say. Instead of returning the result from every call, you need to pass it into every call (aka "accumulator"), and only return from the terminal case:
let rec countCh (s:string) n ch countSoFar =
if n >= s.Length || n < 0 then countSoFar
elif s.[n] = ch then countCh s (n+1) ch (countSoFar+1)
else countCh s (n+1) ch countSoFar
// Usage:
countCh "aaaabbbccc" 5 'b' 0
This way, every recursive call is the "last" call (i.e. the function doesn't do anything with the result, but passes it straight out to its own caller). This is called "tail recursion" and can be compiled to work in constant stack space (as opposed to linear).
I agree with the other answers, but I'd like to help you with your original question. You need to indent the function, and you have an off by one bug:
let rec countCh (s:string, n:int, ch:char) =
match s, n, ch with
| s, n, _ when n >= s.Length-1 -> 0 //p1
| s, _, _ when n < 0 -> 0 //p2
| s, n, ch when s.[n+1] <> ch -> countCh(s, n+2, ch) //p3
| s, n, ch when s.[n+1] = ch -> 1 + countCh(s, n+2, ch) //p4
I'd suggest to not write it yourself, but ask the library functions for help:
let countCh (s: string, n, c) =
s.Substring(n+1).ToCharArray()
|> Seq.filter ((=) c)
|> Seq.length
Or use Seq.skip, along with the fact that you can drop the conversion to character array:
let countCh (s: string, n, c) =
s
|> Seq.skip (n + 1)
|> Seq.filter ((=) c)
|> Seq.length

return value to break function

I am completely new to F# (started using it today) and relatively new to functional programming (I have minor experience with Lisp). I want to exit a function by returning a value when a certain condition is met so that the rest of the loop is not executed. Here is a C# illustration of what I want to do:
bool CheckRow (int n, int i)
{
for(int j = 0; j < 9; j++)
if (n == sudoku[i][j])
return false;
return true;
}
I tried implementing the same function in F# like this (sudoku is an array2D):
let CheckRow (n : int) (i : int) : bool =
for j = 0 to 8 do
if (n = sudoku.[i, j]) then
false
true
However, I get the following error at false within the if: "This expression was expected to have type unit but here has type bool". What is the proper way to "return" from within a F# function?
Higher-order functions are nice of course, but at some point someone has to write a loop (e.g. to implement the higher-order function), and that'll eventually be you, so it's nice to know how to write loops in F#. There is no early return from a for loop in F#, but other types of loops do allow this:
// While loop, imperative style
let checkRow n i =
let mutable clear = true
let mutable j = 0
while clear && j < 9 do
clear <- n <> sudoku.[i, j]
j <- j + 1
clear
// Tail-recursive style - more idiomatic F#
let checkRow n i =
let rec loop j =
if j = 9 then true
elif sudoku.[i, j] = n then false
else loop (j + 1)
loop 0
Normally you shouldn't need to break function earlier but rather end recursion on some case, otherwise call function recursively. Here recursion might be hidden because you are operating on lists or matrixes.
List.forall is one of those functions that implement recursion over the list and returns the result on the first occasion. You could write you function this way:
let CheckRow (expectedValue : int) (rowIndex : int) =
[0..8] |> List.forall (fun colIndex ->
sudoku.[rowIndex, colIndex] <> expectedValue)

Resources