Scott Nimrod
Scott Nimrod

Reputation: 11595

Why am I forced to return a typed value for None?

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

Answers (2)

Alexey Romanov
Alexey Romanov

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

Mark Seemann
Mark Seemann

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

Related Questions