Are option types reset?

Here is the type of option in F #:

type Option<'a> = | Some of 'a | None 

Suppose I have Option of Option :

 type Option2<'a> = | O of Option<'a> | None 

Does it fall apart into just one Option ?

+6
source share
3 answers

No, F # has a nominal type system. Structurally equivalent types are incompatible. Thus, even if you had Option and Option2 exactly the same (except for the name), these types would be different. Your case is different, similar to asking if the int lists and the list of int lists match.

 let hasOptionType (_ : Option<_>) = () let hasOption2Type (_ : Option2<_>) = () let o = Option.None let o2 = Option2.None hasOptionType o //hasOption2Type o // does not compile //hasOptionType o2 // does not compile hasOption2Type o2 

You may have type aliases, although they work in both directions:

 type IntOption = Option<int> let isOptionOfInt (_ : Option<int>) = () let isIntOption (_ : IntOption) = () let i = IntOption.None let i2 = Option<int>.None isOptionOfInt i isOptionOfInt i2 isIntOption i isIntOption i2 
+5
source

Your question is a bit confusing because you are talking about Option Option , but then showing a type that is your own Option2 type containing Option .

I'm going to suggest that your question is really this: Some (Some x) collapses to Some x ?

The answer is no. This collapse will indirectly change the type, and you will lose some of the type security that Option provides. And the distinction between minimized and non-minimized versions can be important. Take this example.

 match List.tryHead [Some 1; None; Some 2] with | Some (Some x) -> sprintf "The first item exists with a value of %i" x | Some None -> "The first item exists but it has no value" | None -> "The list was empty" 

The List.tryHead function returns the first element of the list, or None if the list is empty. We give it the Option<int> list so that it returns Option<Option<int>>

We can match return values ​​to cover all possible cases of this type of return. This can be useful if you want to handle these cases differently.

But we still have the opportunity to consider Some None and None as equivalent:

 match List.tryHead [Some 1; None; Some 2] with | Some (Some x) -> sprintf "The first item exists with a value of %i" x | _ -> "No value found" 
+4
source

No, the types of options you defined will not be automatically combined into any other type. They are separate discriminatory unions and should be treated as such.

Take the following example, which shows how you should map patterns and plot Option2 values:

 let info x = match x with | O (Some i) -> sprintf "Found %d" i | O (Option.None) -> "The wrapping Option2 contained None" | Option2.None -> "The wrapper was None" System.Console.WriteLine(info (O (Some 3))) System.Console.WriteLine(info (O Option.None)) System.Console.WriteLine(info Option2.None) // prints: // Found 3 // The wrapping Option2 contained None // The wrapper was None 
+1
source

Source: https://habr.com/ru/post/1013129/


All Articles