How to get min value from array in F#? - f#

This is F# code as close as I can write to find the min value of an array:
let temp = 0
let getArrayMinValue (a : Array) =
if a.Length > 0 then (
for i = 0 to a.Length do
let temp = ( if temp > a.[i] then a.[i] else temp ) in ()
)
I have two questions:
First, a.[i] has compiling error: The field, constructor or member 'Item' is not defined.
Second, the in () is requried, otherwise, there is compiling error "Block following this let is unfinished. Expect an expression". I do not quite understand this part.
Thanks in advance for your help.

Can't you use Array.min to find the minimum element, something like below:
let numbers =[|1..10|]
printfn "%A" (numbers |> Array.min)
Coming to you program, you have to use something like:
let getArrayMinValue (a : int[]) =
and not a: Array You can even do a: 'T[] but since you are comparig the value of the elements against temp it will probably constraint it to int.
Coming to the other error, make temp mutable: let mutable temp = 0 and assign value using <- operator. Here is your whole code:
let mutable temp = 0
let getArrayMinValue (a : 'T[]) =
if a.Length > 0 then (
for i = 0 to a.Length do
temp <- ( if temp > a.[i] then a.[i] else temp )
)

Related

Why does this function using IndexOf always return 0?

I have this function that checks the number of occurrences of a pattern in a string. The problem is that is keeps returning 0 no matter the input. The most frustrating part is that it worked 2 min ago and I did not change anything.
let Counter (text : string) (pattern : string) =
let mutable count = 0
let mutable i = 0
while ((i = text.IndexOf(pattern, i)) <> false) do
i <- i + pattern.Length
count <- count + 1
count
The main problem is that it looks like you're trying to assign a new value to i inside the test in the while loop, but the = operator tests equality and does not perform assignment. The <- assignment operator has return type unit (it does not return the assigned value), so the fix can't be as simple as replacing the call to = with a call to <-.
The most straightforward fix is probably to break that test out into a separate inner function:
let counter (text : string) (pattern : string) =
let mutable i = 0
let moveNext() =
i <- text.IndexOf(pattern, i)
i
let mutable count = 0
while (moveNext() >= 0) do
i <- i + pattern.Length
count <- count + 1
count
However, note that this is not idiomatic F# code. Instead, I'd write it like this:
let counter (text : string) (pattern : string) =
let rec countFrom (i:int) total =
match text.IndexOf(pattern, i) with
| j when j >= 0 -> countFrom (j+pattern.Length) (total+1)
| _ -> total
countFrom 0 0

This expression was expected to have type 'unit' but here has type ''a []'

The following code was an attempt at a recursive bubble sort in F#, where I received the error
"This expression was expected to have type 'unit' but here has type ''a []'"
for the middle three lines:
let swap i j (arr : 'a []) =
let tmp = arr.[i]
arr.[i] <- arr.[j]
arr.[j] <- tmp
let rec recursiveBubbleSort i j (sequence : 'a []) =
if i = sequence.Length then sequence //error
elif j = sequence.Length then recursiveBubbleSort (i+1) 0 sequence //error
elif sequence.[i] > sequence.[j] then swap i j sequence //error
recursiveBubbleSort i (j+1) sequence
This is really puzzling me, as all of the resources I have found haven't sufficiently explained or implied why this is actually occurring. Any help would be greatly appreaciated.
I think this is what you wanted to write:
let rec recursiveBubbleSort i j (sequence : 'a []) =
if i = sequence.Length then sequence
elif j = sequence.Length then recursiveBubbleSort (i+1) 0 sequence
else
if sequence.[i] > sequence.[j] then swap i j sequence |> ignore
recursiveBubbleSort i (j+1) sequence
So, the last elif you wrote has to be an else, within that else there is another if that checks whether to perform the swap or not.
All if .. then, including elif or not, must end with an else unless it's a unit expression (as the call to swap).
That's why you were getting that error.
Finally note that your comparison is inverted, you will sort the list in descending order.

Issue With Factorial Function

I have been trying to write a program which prints out a factorial without actually using recursion.
Here is the code
let factorial x =
let mutable n = x
while n > 0 do
let result = n*(n-1)
n <- (n-1)
result
The issue is that when I try to run the code it tells me that the expected result is a unit, whereas the input is clearly an integer, which obviously results in an error. However, I have checked all my variables and the compiler interprets them as integers, so what is the issue
There are several issues with your code here, you must keep in mind indentation in f# is very important, for you want to do your code should be:
let factorial x =
let mutable n = x
let mutable result = 1
while n > 0 do
result <- n * (n-1)
n <- (n - 1)
result
You were declaring the result variable inside the while scope and returning it outside it. Your code however is incorrect, I took the liberty of modify it, here what I did:
let factorial x =
let mutable n = x
let mutable result = 1
while n >= 1 do
result <- result * n
n <- (n - 1)
result

F# Parallel.ForEach invalid method overload

Creating a Parallel.ForEach expression of this form:
let low = max 1 (k-m)
let high = min (k-1) n
let rangesize = (high+1-low)/(PROCS*3)
Parallel.ForEach(Partitioner.Create(low, high+1, rangesize), (fun j ->
let i = k - j
if x.[i-1] = y.[j-1] then
a.[i] <- b.[i-1] + 1
else
a.[i] <- max c.[i] c.[i-1]
)) |> ignore
Causes me to receive the error: No overloads match for method 'ForEach'. However I am using the Parallel.ForEach<TSource> Method (Partitioner<TSource>, Action<TSource>) and it seems right to me. Am I missing something?
Edited: I am trying to obtain the same results as the code below (that does not use a Partitioner):
let low = max 1 (k-m)
let high = min (k-1) n
let rangesize = (high+1-low)/(PROCS*3)
let A = [| low .. high |]
Parallel.ForEach(A, fun (j:int) ->
let i = k - j
if x.[i-1] = y.[j-1] then
a.[i] <- b.[i-1] + 1
else
a.[i] <- max c.[i] c.[i-1]
) |> ignore
Are you sure that you have opened all necessary namespaces, all the values you are using (low, high and PROCS) are defined and that your code does not accidentally redefine some of the names that you're using (like Partitioner)?
I created a very simple F# script with this code and it seems to be working fine (I refactored the code to create a partitioner called p, but that does not affect the behavior):
open System.Threading.Tasks
open System.Collections.Concurrent
let PROCS = 10
let low, high = 0, 100
let p = Partitioner.Create(low, high+1, high+1-low/(PROCS*3))
Parallel.ForEach(p, (fun j ->
printfn "%A" j // Print the desired range (using %A as it is a tuple)
)) |> ignore
It is important that the value j is actually a pair of type int * int, so if the body uses it in a wrong way (e.g. as an int), you will get the error. In that case, you can add a type annotation to j and you would get a more useful error elsewhere:
Parallel.ForEach(p, (fun (j:int * int) ->
printfn "%d" j // Error here, because `j` is used as an int, but it is a pair!
)) |> ignore
This means that if you want to perform something for all j values in the original range, you need to write something like this:
Parallel.ForEach(p, (fun (loJ, hiJ) ->
for j in loJ .. hiJ - 1 do // Iterate over all js in this partition
printfn "%d" j // process the current j
)) |> ignore
Aside, I guess that the last argument to Partitioner.Create should actually be (high+1-low)/(PROCS*3) - you probably want to divide the total number of steps, not just the low value.

immutable in F#

I know that variables in F# are immutable by default.
But, for example in F# interactive:
> let x = 4;;
val x : int = 4
> let x = 5;;
val x : int = 5
> x;;
val it : int = 5
>
So, I assign 4 to x, then 5 to x and it's changing. Is it correct? Should it give some error or warning? Or I just don't understand how it works?
When you write let x = 3, you are binding the identifier x to the value 3. If you do that a second time in the same scope, you are declaring a new identifier that hides the previous one since it has the same name.
Mutating a value in F# is done via the destructive update operator, <-. This will fail for immutable values, i.e.:
> let x = 3;;
val x : int = 3
> x <- 5;;
x <- 5;;
^^^^^^
stdin(2,1): error FS0027: This value is not mutable
To declare a mutable variable, add mutable after let:
let mutable x = 5;;
val mutable x : int = 5
> x <- 6;;
val it : unit = ()
> x;;
val it : int = 6
But what's the difference between the two, you might ask? An example may be enough:
let i = 0;
while i < 10 do
let i = i + 1
()
Despite the appearances, this is an infinite loop. The i declared inside the loop is a different i that hides the outer one. The outer one is immutable, so it always keeps its value 0 and the loop never ends. The correct way to write this is with a mutable variable:
let mutable i = 0;
while i < 10 do
i <- i + 1
()
x is not changed, it's just hidden by next declaration.
For example:
> let x = 4;;
val x : int = 4
> let x = "abc";;
val x : string = "abc"
>
You're not assigning 5 to x, you are defining a new variable.
The following example shows that there are two distinct variables.
(It also shows that you can "access" the old x if it is in a closure, used by another function):
let x = 5;;
let f y = y+x;;
f 10;;
let x = 0;;
f 10;;
yields
>
val x : int = 5
>
val f : int -> int
> val it : int = 15
>
val x : int = 0
> val it : int = 15
as you see, both calls to f use the first variable x. The definition let x = 0;; defines a new variable x, but does not redefines f.
Here's a minimal example illustrating identifier "shadowing" (i.e. hiding) in F#:
let x = 0
do //introduce a new lexical scope
let x = 1 //"shadow" (i.e. hide) the previous definition of x
printfn "%i" x //prints 1
//return to outer lexical scope
printfn "%i" x //prints 0, proving that our outer definition of x was not mutated by our inner definition of x
Your example is actually a bit more complex, because you are working in the F# Interactive (FSI). FSI dynamically emits code that looks something like the following in your example:
module FSI_0001 =
let x = 4;;
open FSI_0001 //x = 4 is now available in the top level scope
module FSI_0002 =
let x = 5;;
open FSI_0002 //x = 5 is now available in the top level scope, hiding x = 4
module FSI_0003 =
let it = x;;
open FSI_0003
//... subsequent interactions

Resources