How to check in f# if the set is Empty? - f#

How can I check if the set is empty, I have implemented the following code if the set has an empty set then I should get the value true else false, for example: [1; 2; []] this set should result in true and if the set is [1; 2; 3] this should result in false because this one does not have an empty set in it. Following is the code that gives me an error:
let rec isEmpty S =
match S with
|[] -> true
|_ -> false
|e::rest -> ([]=e) || (isEmpty [] rest)

Unfortunately for your use case F# is quite a bit more 'strongly typed' than you would like here.
In F# a value like [1; 2; 3] is an int list, and an int list won't accept a value like [1; 2; []].
Maybe you could try to define a new (recursive) datatype for your problem.

Related

Try to get all or nothing from a sequence based on a precondition

The following code will not work as I expected it to:
// Gets all or nothing. If predicate is false for at least one item
// in the sequence, returns None. If seq is empty, returns the empty seq.
let tryGetAllOrNone predicate (source: seq<_>) =
let mutable condition = true
let resultSeq =
seq {
use e = source.GetEnumerator()
while condition && e.MoveNext() && (condition <- predicate e.Current; condition) do
yield e.Current
}
if condition then Some resultSeq
else None
The reason is quite clear: a sequence is lazily evaluated, which means that here the if statement will be evaluated first, returning the sequence. Then, when we consume the resulting sequence we will always get Some results, until the condition turns false:
// expect: None (predicate is false for the first item)
> [1;2;3] |> tryGetAllOrNone (fun x -> x = 2);;
val it : seq<int> option = Some (seq [])
// expect None (predicate is false for the second item)
> [1;2;3] |> tryGetAllOrNone (fun x -> x = 1);;
val it : seq<int> option = Some (seq [1])
// correct (predicate is always true)
> [1;2;3] |> tryGetAllOrNone (fun x -> x > 0);;
val it : seq<int> option = Some (seq [1; 2; 3])
I might just have to consume the sequence first, i.e. by using [...yield ...] instead of seq { .. yield ...}, but maybe there's a simpler solution that retains the laziness (just asking the question makes it sound backwards, so my gut tells me: consume first, right)?
EDIT: thinking about this is a tad longer has me come to the conclusion that what I'm asking is not possible. You cannot first lazily return one after the other from a sequence and then, upon hitting an invalid item, say: "hey, all those items you got thus far, give them back, if one is invalid, all are invalid!".
Leaving it out here nonetheless in case it helps someone else or in case someone has a better idea ;).
You are right that, in general, you will need to iterate over the whole sequence until you can return None or Some. If the last element of the sequence does not satsify the condition, then you need to first read all the preceding elements until you know that you have failed.
The only optimization you can do is that you can return None as soon as you find a first element that does not satisfy the condition. This is slightly better than building the whole sequence and then checking if the condition was false for any of the elemnetns (in that, if an earlier element fails to satisfy the condition, you can return None sooner). The following implementation does that:
// Gets all or nothing. If predicate is false for at least one item
// in the sequence, returns None. If seq is empty, returns the empty seq.
let tryGetAllOrNone predicate (source: seq<_>) =
let results = ResizeArray<_>()
let mutable failed = false
use e = source.GetEnumerator()
while not failed && e.MoveNext() do
if not (predicate e.Current) then failed <- true
else results.Add(e.Current)
if failed then None
else Some(seq results)

How do I check for reference equality in F#?

F# uses structural equality for the = operator, which is almost always what you want:
let a = [1; 2; 3]
let b = [1; 2; 3]
printfn "%A" (a = b) // Prints "true"
But in some algorithms, it can be important to be able to ask "Are these two things the same object?" This can help with detecting cycles in a graph, for example. So how do I ask for reference equality in F#? I.e., how do I write the isSameObject function below?
let isSameObject x y = ???
let a = [1; 2; 3]
let b = [1; 2; 3]
let a' = a
printfn "%A" (isSameObject a b) // Prints "false"
printfn "%A" (isSameObject a a') // Prints "true"
The answer, it turns out, is to use LanguagePrimitives.PhysicalEquality:
let isSameObject = LanguagePrimitives.PhysicalEquality
let a = [1; 2; 3]
let b = [1; 2; 3]
let a' = a
printfn "%A" (isSameObject a b) // Prints "false"
printfn "%A" (isSameObject a a') // Prints "true"
There was precisely one question I could find on Stack Overflow that asked about this:
short-cutting equality checking in F#? And since that question's subject almost made me glance right past it, I figured I would ask (and answer) the question again. Hopefully this question's subject line will make it easier to find when Googling for terms like "referential equality in F#".
What about obj.ReferenceEquals?
In a comment, Fyodor Soikin asks what's wrong with obj.ReferenceEquals. The answer is "not much", but there are two ways in which LanguagePrimitives.PhysicalEquality is better than obj.ReferenceEquals for most F# code:
1) PhysicalEquality throws a compiler error when you pass it two different types, while obj.ReferenceEquals just takes two objs and therefore happily tries to compare an int list to char list:
let a = [1;2;3]
let b = ['a';'b';'c']
obj.ReferenceEquals(a,b) // Returns false
LanguagePrimitives.PhysicalEquality a b // Compiler error
2) PhysicalEquality won't let you compare value types, only reference types. obj.ReferenceEquals will let you compare two value types, and will implicitly box them first. But it boxes each one separately, meaning that it will always return false even when you gave it the "same" value object:
let n = 3
let n' = n
obj.ReferenceEquals(n,n') // Returns false!
LanguagePrimitives.PhysicalEquality n n' // Compiler error
And, of course, there's one other difference, which boils down to personal preference and ease-of-use. PhysicalEquality takes curried-style parameters, which plays nicely with type inference and partial application. obj.ReferenceEquals takes tupled-style parameters, which means it's slightly uglier to use.
For all these reasons, LanguagePrimitives.PhysicalEquality is better to use, in almost every scenario, than obj.ReferenceEquals.

Unexpected keyword 'val' in definition

Learning F# as part of my course, and can do some cool things, but something has been bugging me, whenever I use the val keyword, I get an error. I think it could be due to not declaring something in script, but I don't really know.
module Prime
#light
let nums = [1; 2; 3; 4; 5];;
val nums : list<int>
let rec sum list =
match list with
| h::tail -> (sum tail) + h
| [] -> 0
val sum : list<int> -> int
I get (line 5):
Error 1 Unexpected keyword 'val' in definition . Expected incomplete structured construct at or before this point or other token
Any ideas?
The val keyword in F# (unlike 'val' in ML) is used to declare a field in a class or structure type without initializing it.
http://msdn.microsoft.com/en-us/library/dd469494.aspx
if you want to define mutable value in the Module you can use
let mutable...
By the way, if you define the value with the same name (like 'nums') twice or more times then the effective value for the compiler will be latest defined in the scope.
So actually, I had misread the coursework set out, annoyingly the papers use val to define what the expected output of the function is, as opposed to using it as the keyword it is meant to be. Hence my confusion and lots of head scratching.
This looks like F# interactive output mixed in with code.
If I type this into FSI:
let nums = [1; 2; 3; 4; 5];;
The output is
val nums : int list = [1; 2; 3; 4; 5]
Note that ;; is where FSI parses and runs input. You wouldn't have this in non-interactive code. The output might differ because of an older version or editing, but nontheless, it doesn't belong in code.
Coincidentally, val is also a rarely used F# keyword for explicit fields. Hence the strange error message.
The val keyword is used to declare a field ; it must be used inside a type definition (class or structure). Since in your code the variable nums is already defined and as the list type inferred by F# type inference engine, there is no need for your val line.
An example of val keyword usage is (from msdn) :
type MyType() =
let mutable myInt1 = 10
[<DefaultValue>] val mutable myInt2 : int
[<DefaultValue>] val mutable myString : string
member this.SetValsAndPrint( i: int, str: string) =
myInt1 <- i
this.myInt2 <- i + 1
this.myString <- str
printfn "%d %d %s" myInt1 (this.myInt2) (this.myString)

Create a list by selecting from another in F#

I am new to F#, I have been going through first few chapters of F# for C# developers. I am stuck at this point and I need help. If anybody thinks I am going against the purpose of this website, please let me know I will remove my question.
I have the following list
let list1 = [0..100]
I want to create a list from the list above but select only the numbers that are divisible by 5. I am trying the following.
let list2 = [for i in list1 do yield if i%5=0 then i]
But the above is giving me compile error as follows. Why is that ? Why it could not simply infer the type int?
Program.fs(6,52): error FS0001: This expression was expected to have
type
unit but here has type
int
You need to move the yield inside the if:
let list2 = [for i in list1 do if i%5=0 then yield i]
An if ... then expression with no else can only return something of type unit, because the whole expression has to have a value, and if the condition is not satisfied the compiler won't just make up a value of any other type.
In your case you were trying to say that the expression should produce an int if the condition was satisfied, and nothing otherwise; the proper way to do that is to make the yield conditional as well. Otherwise you are saying you always want to produce a value, even if the condition isn't satisfied.
Since you want to filter, it's easier to just use the built-in filter function:
let list2 = list1 |> List.filter (fun x -> x % 5 = 0)
Given your list1, it produces the output
[0; 5; 10; 15; 20; 25; 30; 35; 40; 45; 50; 55; 60; 65; 70; 75; 80; 85; 90; 95; 100]

Why does this produce a value restriction exception?

I've created a function that returns a list containing only the even indexes as shown below:
let rec removeOddIdx xs =
match xs with
|[] -> []
|h::t -> (if t.Length % 2 = 0 then
[h]#removeOddIdx t
else
removeOddIdx t)
It works fine when I call it:
removeOddIdx [1;2;3;];;
However when I call it with an empty list:
removeOddIdx [];;
I get a Value Restriction exception - how come?
I've read up on value restrictions but I don't understand why it happens in my case.
Here is the precise error message:
Testing.fs(13,1): error FS0030: Value restriction. The value 'it' has been inferred to have generic type
val it : '_a list
Either define 'it' as a simple data term, make it a function with explicit arguments or, if you do not intend for it to be generic, add a type annotation.
The problem you're having is that the compiler doesn't know what type to give the return value. When you pass it [1;2;3] it can infer that the return type is int list, but if you pass it [], what is the type of the return value? It cannot be inferred from the usage, so you get a value restriction error.
One solution is to give the parameter a type like so:
> removeOddIdx ([]:int list);;
val it : int list = []
The other is to make the function specific rather than generic like this:
> let rec removeOddIdx (xs:int list) =
match xs with
|[] -> []
|h::t -> (if t.Length % 2 = 0 then
[h]#removeOddIdx t
else
removeOddIdx t);;
val removeOddIdx : xs:int list -> int list
> removeOddIdx [];;
val it : int list = []
Outside of the repl this is unlikely to be an issue since the parameter type is likely to be inferred from elsewhere in your code.

Resources