fahadash
fahadash

Reputation: 3281

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

Upvotes: 1

Views: 108

Answers (2)

Mark Seemann
Mark Seemann

Reputation: 233135

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]

Upvotes: 4

Ganesh Sittampalam
Ganesh Sittampalam

Reputation: 29100

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.

Upvotes: 4

Related Questions