Reputation: 11595
Why am I forced to return a typed value for None?
let getHand = function
| Some(card1, card2) -> card1, card2
| None -> // ?
In my case, I want to deal a hand. But it doesn't make sense for me to still deal a hand if no hand exists via Options.
What am I not considering? What pattern should I be using?
Specifically, if no hand exists, then I want to grab a full deck. Why would a method yield a complex typed result if no result exists?
| None -> // Why am I still required to yield a typed result
Upvotes: 1
Views: 104
Reputation: 170713
An alternative solution to Mark Seemann's answer is to return option
as well. You could write (changed because your own function would become trivial):
let getFirstCard = function
| Some (card1, card2) -> Some card1
| None -> None
or better Option.map (fun (card1, card2) -> card1)
.
The final (and generally bad) solution is to throw an exception on None
using Option.get
.
Upvotes: 3
Reputation: 233125
All values in F# have types. Functions do as well.
The getHand
function looks like it takes as input an option
value. Since an option
value is a Discriminated Union, the function must address both cases of possible input. The compiler and the type system helps you do that.
A part of a function's type is its return value. In F#, a function can only have a single return type (this is also true for C#). Thus, you'll need to address both the Some
and the None
case, and make the function return the same type in both cases. Sometimes, though, that 'same type' can be another Discriminated Union.
From the wording of your question, it sounds like you want to return some cards in both cases, so perhaps return a list of cards:
let getHand = function
| Some(card1, card2) -> [card1; card2]
| None -> []
Here, I've returned an empty list in the None
case, but if you wish, you can instead populate the return value with a default list.
Upvotes: 9