Define default value for discriminated union

  • A+
Category:Languages

I would like to define a default value for a discriminated union, like this:

open System.Linq  type Result = | Ok | Error  let results : seq<Result> = [] |> Seq.ofList  let firstResult = results.FirstOrDefault() // I want firstResult to be Error, currently it is null. 

option<'a> works in this way (firstResult would be None), so it should be possible. Thanks for your help.

Edit: I'm using SQLDataProvider and would like to write code like

let userEmail =     query {         for user in dbContext.Public.Users do         where (user.Id = 42)         select (Ok user.Email)         headOrDefault         // should result in Error         // when no user with Id=42 exists      } 

My actual result type looks like this:

type Result<'a> = | Ok of 'a | Failure of string // Expected, e. g. trying to log in with a wrong password | Error // Unexpected 

Returning an option, the caller would not be able to differentiate between failures and errors.


In general F# avoids the concept of defaults, instead making everything as explicit as possible. It's more idiomatic to return an option and for the caller to decide what to default to for a particular use case.

The FirstOrDefault method can only return .NET's default value for any type. So for any class it would return null, and for a number it would return zero.

I would recommend this approach instead assuming your desired default is Ok:

results |> Seq.tryHead |> Option.defaultValue Ok 

Comment

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: