Search code examples
f#flatten

How to use Option.flatten with None?


There is an error when applying the flatten function on the Option module:

let flatten  =
function
| None          -> None
| Some innerOpt -> innerOpt

This only works with imputs like: Some Some 1. But if the input is "None" then I get this error:

flatten None 

error FS0030: Value restriction. The value 'it' has been inferred to have generic type
    val it : '_a option
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.

How is flatten supposed to work with generics in the None case?


Solution

  • flatten is a generic function with type 'a option option -> 'a option. The compiler cannot infer the type parameter to use for the automatic REPL variable it (which is the result of the previous expression) when the argument is None. You can specify your own variable:

    let it : int option = flatten None;;
    

    explicitly specify the type of None:

    flatten (None : int option option);;
    

    or

    flatten (Option<int option>.None);;
    

    or specify the generic parameter explicitly to flatten:

    flatten<int> None;;
    

    this generates a warning which you can remove by making the type parameter to flatten explicit:

    let flatten<'a> (o : 'a option option) =
        match o with
        | None          -> None
        | Some innerOpt -> innerOpt