Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

F# Is this a bug in Option.map

Tags:

f#

f#-3.0

f#-data

Given the following code:

let mapOption (f : ('a -> 'b)) (x : 'a option) =
    match x with
    | Some x -> Some(f(x))
    | None -> None

let mapOptions (f : ('a -> 'b)) (xs : 'a option list) : 'b option list =
    xs
    |> List.map (fun (x : 'a option) -> mapOption f x)

let myList = [None; Some 1; Some 2; None]

let a = myList |> mapOptions (fun x -> x + 2)

let b = myList |> List.map(fun x-> x |> Option.map(fun y -> y + 2))

Why is the result for a and b equal to :

[null; Some 3; Some 4; null] or val it : int option list = [null; Some 3; Some 4; null]

Should it not be:

[None; Some 3; Some 4; None]
like image 419
Stuart Avatar asked Mar 15 '23 09:03

Stuart


1 Answers

None is represented by null in the CLR. You can see that by experimenting with FSI:

> [Some 3; None];;
val it : int option list = [Some 3; null]

It still works, though::

> [Some 3; None] |> List.choose id;;
val it : int list = [3]

So [null; Some 3; Some 4; null] is the same as [None; Some 3; Some 4; None]:

> a = [None; Some 3; Some 4; None];;
val it : bool = true

where a is the value from the OP.

like image 62
Mark Seemann Avatar answered Mar 24 '23 13:03

Mark Seemann