Reputation: 25
I am attempting to double the elements of a given list but am getting an error "
This expression was expected to have type
''a list'
but here has type
'int'
"
when defining a new list
let list1 = [5;10;15;20;25;30]
let rec doubleListElements list =
match list with
|[]-> 0
|head::tail ->
let doubledList = [head*2::doubleListElements tail]
0
let printList = doubleListElements list1
printfn "%A" printList
I am very new to f# and don't fully understand how things work, I am more used to an object oriented approach
Upvotes: 2
Views: 443
Reputation:
You can make use of different kinds of data structures, such as sequences:
namespace FSharpBasics
module DoubleList =
let private list1 = [ 5; 10; 15; 20; 25; 30 ]
(*operations*)
let doubleList (list: List<int>) =
Seq.init list.Length (fun index -> list.[index] * 2)
|> Seq.toList
[<EntryPoint>]
let main argv =
doubleList list1
|> printf "%A"
System.Console.ReadKey() |> ignore
0
Upvotes: 0
Reputation: 16194
The function in your question will work with some changes:
let rec doubleListElements list =
match list with
| [] -> []
| head::tail -> head*2::doubleListElements tail
First important thing to keep in mind is "what do I want to give to and receive from this function". In your case, your input is a int list
and desired output is an int list
. This means wherever your function returns a value it must be an int list
. Your function has two places where a value is returned:
| [] -> [] // return empty list
| head::tail ->
head*2::doubleListElements tail // return a list (but recurse)
In your original function your return values are always 0
which of course doesn't satisfy the int list
return type.
|[]-> 0 // return value
|head::tail ->
let doubledList = [head*2::doubleListElements tail]
0 // return value
In this expression, a doubledList
is created but that value is essentially discarded because it is unused and it's not the return value. The return value is the final value in the expression: 0
. I think this is a very common mistake to see as people learn functional languages that are expression-based coming from imperative statement-based languages.
In this particular expression only the final value matters. In a statement-based language you might've mutated some program state before returning a value (which is also totally possible in F# but mutability is usually avoided).
let foo x =
let y = x + x // the value of this expression is discarded: y is unused
x * x // the value of this expression is returned
The only other necessary change is to not wrap your returned list in another list in each recursion. head*2::doubleListElements tail
is just a list. [head*2::doubleListElements tail]
is the same list inside of another list because it's wrapped in square bracket list literals. After that change it works:
val printList : int list = [10; 20; 30; 40; 50; 60]
Upvotes: 3