F# return from loop - f#

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

Related

Why does this definition returns a function?

I found the following in the book Expert F# 4.0, Fourth Edition, by Don Syme, Adam Granicz, and Antonio Cisternino:
let generateStamp =
let mutable count = 0
(fun () -> count <- count + 1; count)
I could not understand why this code creates a function:
val generateStamp : (unit -> int)
It looks to me like its signature should be
val generateStamp : int
For example, the following code:
let gS =
let mutable count = 0
(printfn "%d" count; count)
creates an int value:
val gS : int = 0
As I understand it the code (fun () -> count <- count + 1; count) should first evaluate the lambda and then count. So the value of generateStamp should be just count, as it is in the definition of gS. What am I missing?
In any block of F# code, the last expression in that block will be the value of that block. A block can be defined in one of two ways: by indentation, or with ; between the block's expressions.
The expression fun () -> other expressions here creates a function. Since that's the last expression in the code block under let generateStamp =, that's the value that gets stored in generateStamp.
Your confusion is that you think that the expressions inside the fun () are going to be evaluated immediately as part of the value of generateStamp, but they're not. They are defining the body of the anonymous function returned by the fun () expression. You're absolutely right that inside that block of code, count is the last expression and so it's the thing returned by that function. But the fun () expression creates a function, which will only evaluate its contents later when it is called. It does not evaluate its contents immediately.
By contrast, the expression (printfn "%d" count; count) is a block of code with two expressions in it. It is not a function, so it will be immediately evaluated. Its last expression is count, so the value of the code block (printfn "%d" count; count) is count. Since the (printfn "%d" count; count) block is being evaluated immediately, you can mentally replace it with count. And so the value of gS is count, whereas the value of generateStamp is a function that will return count when it's evaluated.
It's syntactic trickery. The last ; count part is actually part of the lambda, not the next expression after it.
Here are some simplified examples to work through:
let x = 1; 2; 3 // x = 3
let f x = 1; 2; 3 // f is a function
let y = f 5 // y = 3, result of calling function "f"
let f = fun x -> 1; 2; 3 // Equivalent to the previous definition of "f"
let y = f 5 // y = 3, same as above
let f =
fun x -> 1; 2; 3 // Still equivalent
let y = f 5 // y = 3, same as above
let f =
let z = 5
fun x -> 1; 2; 3 // Still equivalent
let y = f 5 // y = 3, same as above
// Your original example. See the similarity?
let generateStamp =
let mutable count = 0
fun () -> count <- count + 1; count
Now, if you wanted to have count be the return value of generateStamp, you'd need to put it either outside the parens or on the next line:
// The following two definitions will make "generateStamp" have type "int"
let generateStamp =
let mutable count = 0
(fun () -> count <- count + 1); count
let generateStamp =
let mutable count = 0
(fun () -> count <- count + 1)
count

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)

How to improve this F# function

I am experienced in C# but new to F# and Functional Programming. Now I am trying to implement a class library in F#. Here is one of the functions:
It takes a list of integers <=9 and change consecutive 9 like 9,9,9,9 to 9, 10, 11, 12. For example [9;9;9;1;4;0;1;9;9;9;9] will be changed to [9; 10; 11; 1; 4; 0; 1; 9; 10; 11; 12].
C# function is trivial:
void ReleaseCap(List<int> items)
{
for (int i = 1; i < items.Count; i++)
{
var current = items[i];
var previous = items[i - 1];
//If curernt value = 9 and previous >=9, then current value should be previous+1
if (current == 9 && previous >= 9)
{
items[i] = previous + 1;
}
}
}
Now is my F# tail recursive one. Instead of loop the List by index, it recursively move item from an initial list to an processed list until everything in the initial list is gone:
let releaseCap items =
let rec loop processed remaining = //tail recursion
match remaining with
| [] -> processed //if nothing left, the job is done.
| current :: rest when current = 9 -> //if current item =9
match processed with
// previous value >= 9, then append previous+1 to the processed list
| previous :: _ when previous >= 9 -> loop (previous+1 :: processed) rest
//if previous < 9, the current one should be just 9
| _ -> loop (current :: processed) rest
//otherwise, just put the current value to the processed list
| current :: rest -> loop (current :: processed) rest
loop [] items |> List.rev
While the C# version is trivial and intuitive, the F# code is verbose and not as intuitive. Is there any part of the F# code can be improved to make it more elegant?
You can reuse existing functions in order to simplify your code.
Normally when you change items in a list you think of a map but in this case you have something to remember from your previous computation which should be passed for each item, so you should aim to fold related functions.
Here's one: List.scan
let releaseCap items =
items
|> List.scan (fun previous current ->
if current = 9 && previous >= 9 then previous + 1
else current) 0
|> List.tail
FP is not just about using recursion instead of loops. Recursion is typically used in basic and reusable functions, then by combining those functions you can solve complex problems.
NOTE: You are comparing your C# solution with your F# solution, but did you notice that apart from the language there is an important difference between both solutions? Your C# solution uses mutability.
In your C# code you correctly assume that the 1st element of the list will never change and start with the 2nd element.
If you include this in the F# code you can skip the match on accumulator.
The result will be a bit simpler.
let reduceCap l =
let rec reduceCapRec acc l =
let previous = List.head acc
match l with
| x::xs ->
if x = 9 && previous >= 9
then reduceCapRec ((previous+1) :: acc) xs
else reduceCapRec (x :: acc) xs
| [] -> acc
reduceCapRec [List.head l] (List.tail l)
|> List.rev
(Although Gustavo's solution is still much better - I'm also new to FP)
I thought fold was the important one! :-)
So:
let list = [9;9;9;1;4;0;1;9;9;9;9]
let incr acc e =
match acc, e with
| h::t, e when e = 9 && h >= 9 -> (h + 1)::acc
| _ -> e::acc
list
|> List.fold incr []
|> List.rev
//val it : int list = [9; 10; 11; 1; 4; 0; 1; 9; 10; 11; 12]

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

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);
}

Resources