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]
Related
I have an xUnit test that accepts three arguments, a list, an integer and a tuple, however, when I run it it's failing with the following error:
System.InvalidOperationException: The test method expected 4 parameter values, but 3 parameter values were provided.
There are only three items in the test data I'm providing.
[<AbstractClass>]
type TestCases (data: seq<obj[]>) =
member this.Data = data
interface IEnumerable<obj[]> with
member this.GetEnumerator() = this.Data.GetEnumerator()
interface IEnumerable with
member this.GetEnumerator() = (this :> IEnumerable).GetEnumerator()
type SplicingTestCases () =
inherit TestCases (seq {
yield [|box [1; 2; 3; 4;];
box 2;
box ([1;2;],[3;4;])
|]
})
[<Theory>]
[<ClassData(typeof<SplicingTestCases>)>]
let ``Splicing`` testList index expected =
let actual = testList |> splice index
Assert.Equal(expected, actual)
I've exec tried removing a parameter (just to see what happens) like this:
let ``Splicing`` testList index =
let actual = testList |> splice index
Assert.Equal(actual, actual)
Now the error is:
System.InvalidOperationException: The test method expected 2 parameter values, but 3 parameter values were provided.
Any suggestions?
Looks like the tuple is being converted into two separate objects. Not sure yet if this is happening in the F# compilation of in xUnit's interpretation of the tuple.
Yielding the following works though:
[|box [1; 2; 3; 4;];
box 2;
box [1;2;];
box [3;4;];|]
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.
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)
Is there a way to have mutable function arguments in F#, that would allow something like
let mutable i = 9
let somefun n = n <- 12; ()
somefun i
(* *not* a real-world example *)
I do understand that this can be made to work by wrapping it into a record type
type SomeRec = { mutable i: int }
let ri = { i = 9 }
let someotherfun r = r.i <- 12; ()
and that this can be done in a similar fashion for class members. However, even after browsing through the whole F# Language Specification (yes, I did!), there seems to be no syntax to allow the first case, and the compiler appears to be quite unhappy about my trying this. I was hoping there would be some sort of type annotation, but mutable cannot be used in such.
I also know that I should not be doing this sort of thing in the first place, but the first case (int binding) and the second (record type) are semantically identical, and any such objection would hold for both cases equally.
So I think that I am missing something here.
You can use ref as arguments
let v = ref 0
let mutate r =
r := 100
mutate v
printfn "%d" !v
Or byref keyword
let mutable v = 0
let mutate (r : byref<_>) =
r <- 100
mutate &v
printfn "%d" v
Use byref keyword which is equivalent to C# ref.
See Passing by reference.
Is it just me, or does F# not cater for cyclic lists?
I looked at the FSharpList<T> class via reflector, and noticed, that neither the 'structural equals' or the length methods check for cycles. I can only guess if 2 such primitive functions does not check, that most list functions would not do this either.
If cyclic lists are not supported, why is that?
Thanks
PS: Am I even looking at the right list class?
There are many different lists/collection types in F#.
F# list type. As Chris said, you cannot initialize a recursive value of this type, because the type is not lazy and not mutable (Immutability means that you have to create it at once and the fact that it's not lazy means that you can't use F# recursive values using let rec). As ssp said, you could use Reflection to hack it, but that's probably a case that we don't want to discuss.
Another type is seq (which is actually IEnumerable) or the LazyList type from PowerPack. These are lazy, so you can use let rec to create a cyclic value. However, (as far as I know) none of the functions working with them take cyclic lists into account - if you create a cyclic list, it simply means that you're creating an infinite list, so the result of (e.g.) map will be a potentially infinite list.
Here is an example for LazyList type:
#r "FSharp.PowerPack.dll"
// Valid use of value recursion
let rec ones = LazyList.consDelayed 1 (fun () -> ones)
Seq.take 5 l // Gives [1; 1; 1; 1; 1]
The question is what data types can you define yourself. Chris shows a mutable list and if you write operations that modify it, they will affect the entire list (if you interpret it as an infinite data structure).
You can also define a lazy (potentionally cyclic) data type and implement operations that handle cycles, so when you create a cyclic list and project it into another list, it will create cyclic list as a result (and not a potentionally infinite data structure).
The type declaration may look like this (I'm using object type, so that we can use reference equality when checking for cycles):
type CyclicListValue<'a> =
Nil | Cons of 'a * Lazy<CyclicList<'a>>
and CyclicList<'a>(value:CyclicListValue<'a>) =
member x.Value = value
The following map function handles cycles - if you give it a cyclic list, it will return a newly created list with the same cyclic structure:
let map f (cl:CyclicList<_>) =
// 'start' is the first element of the list (used for cycle checking)
// 'l' is the list we're processing
// 'lazyRes' is a function that returns the first cell of the resulting list
// (which is not available on the first call, but can be accessed
// later, because the list is constructed lazily)
let rec mapAux start (l:CyclicList<_>) lazyRes =
match l.Value with
| Nil -> new CyclicList<_>(Nil)
| Cons(v, rest) when rest.Value = start -> lazyRes()
| Cons(v, rest) ->
let value = Cons(f v, lazy mapAux start rest.Value lazyRes)
new CyclicList<_>(value)
let rec res = mapAux cl cl (fun () -> res)
res
The F# list type is essentially a linked list, where each node has a 'next'. This in theory would allow you to create cycles. However, F# lists are immutable. So you could never 'make' this cycle by mutation, you would have to do it at construction time. (Since you couldn't update the last node to loop around to the front.)
You could write this to do it, however the compiler specifically prevents it:
let rec x = 1 :: 2 :: 3 :: x;;
let rec x = 1 :: 2 :: 3 :: x;;
------------------------^^
stdin(1,25): error FS0260: Recursive values cannot appear directly as a construction of the type 'List`1' within a recursive binding. This feature has been removed from the F# language. Consider using a record instead.
If you do want to create a cycle, you could do the following:
> type CustomListNode = { Value : int; mutable Next : CustomListNode option };;
type CustomListNode =
{Value: int;
mutable Next: CustomListNode option;}
> let head = { Value = 1; Next = None };;
val head : CustomListNode = {Value = 1;
Next = null;}
> let head2 = { Value = 2; Next = Some(head) } ;;
val head2 : CustomListNode = {Value = 2;
Next = Some {Value = 1;
Next = null;};}
> head.Next <- Some(head2);;
val it : unit = ()
> head;;
val it : CustomListNode = {Value = 1;
Next = Some {Value = 2;
Next = Some ...;};}
The answer is same for all languages with tail-call optimization support and first-class functions (function types) support: it's so easy to emulate cyclic structures.
let rec x = seq { yield 1; yield! x};;
It's simplest way to emulate that structure by using laziness of seq.
Of course you can hack list representation as described here.
As was said before, your problem here is that the list type is immutable, and for a list to be cyclic you'd have to have it stick itself into its last element, so that doesn't work. You can use sequences, of course.
If you have an existing list and want to create an infinite sequence on top of it that cycles through the list's elements, here's how you could do it:
let round_robin lst =
let rec inner_rr l =
seq {
match l with
| [] ->
yield! inner_rr lst
| h::t ->
yield h
yield! inner_rr t
}
if lst.IsEmpty then Seq.empty else inner_rr []
let listcycler_sequence = round_robin [1;2;3;4;5;6]