user1206480
user1206480

Reputation: 1858

How do I return a specific type of tuple in F#?

This is the code that I am working on:

// RopResult
type RopResult<'TSuccess, 'TMessage> =
    | Success of 'TSuccess * 'TMessage list
    | Failure of 'TMessage list

// result to return
type ResultForClient<'TSuccessObj, 'TMessages> =
    bool * 'TSuccessObj * seq<'TMessages>

// return the above type
let resultToClient =
    function 
    | Success (x, msg) -> true, x, Seq.ofList msg
    | Failure errors -> false, Object(), Seq.ofList errors

The resultToClient function appears to just return a tuple opposed to the specific tuple type of ResultForClient. What am I missing here? On a side note, am I representing the RopResult type correctly in the return. As you can see the RopResult is generic so in case of failure I insert Object(). Does this seem correct?

Upvotes: 0

Views: 83

Answers (2)

Mark Seemann
Mark Seemann

Reputation: 233150

It looks like you're attempting to do Railway Oriented Programming.

am I representing the RopResult type correctly in the return. As you can see the RopResult is generic so in case of failure I insert Object(). Does this seem correct?

No, that doesn't seem to be correct. By using Object(), the inferred type of resultToClient is

RopResult<System.Object,'a> -> ResultForClient<System.Object,'a>

Since ResultForClient is only a type alias, this is equivalent to

RopResult<Object,'a> -> bool * Object * seq<'a>

That is, the return value of the function is bool * Object * seq<'a>. This looks more like a nasty combination of return codes and untyped data than a Fucntional data type. Is that what you had in mind? What do you intend to do with the Object?


The point of Railway Oriented Programming is that the RopResult data type itself carries information about the result of any computation (whether or not it failed), so unless you're trying to interop with some other system that doesn't understand sum types (Discriminated Unions), you'll only be throwing away information by attempting to 'unwrap' the RopResult.

Upvotes: 2

Kevin
Kevin

Reputation: 2291

Specify the return type:

let resultToClient v : ResultForClient<_,_> =
  match v with 
  | Success (x, msg) -> true, x, Seq.ofList msg
  | Failure errors -> false, Object(), Seq.ofList errors

Upvotes: 3

Related Questions