Which of these uses of Option do you prefer and why?

I have some code which used to be:

type Something = Something of int 

let fromInt something = Something something 

let asOption something = 
 if something = 0 then 
   None 
 else 
   Some (something |> fromInt)

…but then I changed ‘asOption’ to:

let asOption something = 
 if something = 0 then 
   None 
 else 
   something |> fromInt |> Some

Which do you think is ‘better’?

I kind of like the way that None/Some start the lines in the first example, makes it more obvious it’s going to be an Option if you only look at that line, but the pipeline seems more idiomatic for F#.

Is there an even better way to do this?
Am I worrying too much about this?

let asOption = 
    function 
    | 0 -> None 
    | value -> Some(Something value)

or

let asOption something = 
    match something with
    | 0 -> None 
    | value -> Some(Something value)

I know in my early F# days I overused the pipe operator; in your code, I don’t feel it is needed to use the operator. It is better to use it for things that are laid out on several lines, or if you are doing things like in your code on a single line, it would be to keep a structure similar over several bindings that are next to each others.

Am I worrying too much about this?

Probably, if you are starting with F#, take it easy and just get your code to do what you need it to, there will come a time where you’ll revisit and do adjustments based on your journey with the language :slight_smile:

Thanks for your reply.

I was starting to think that, by analogy, I was building a town and worrying more about the typeface to be used on the street signs than about whether the streets took people to places they wanted to go.

I was having the same sort of concern with Results, e.g.

try
 …
with 
 | exn -> Error (SomethingError.UnhandledError exn)

…versus…

try
 …
with 
 | exn -> exn |> SomethingError.UnhandledError |> Error

…so I thought I’d ask in case it was important. (I don’t want to learn too many ‘bad habits’ at this early stage.)

I think I’ll go back to doing it my original way unless I have some good reason to do otherwise.

Cheers.

F# Code I Love – Don Syme (advices how to right write code)

Thanks for the link.

I’ve already watched that video but I’d lost the link to it somehow, so now I can bookmark it for watching it again (it’s a very interesting video).

Now I prefer the pipeline here, and if Don disagrees so be it. I like that it shows the transformation in the order it happens from left to right. And the compiler should optimise the pipeline operators away. (if it doesn’t, it should)

In the other form it is completely backwards from the sequence that is intended and even needs brackets because otherwise it wouldn’t be unambiguous.

If it were simple enough that brackets weren’t needed e.g. exn -> Error exn then it makes me feel less icky and I’ll go with it.

But that’s just my preference.

Thanks for giving an alternative viewpoint.

While I like the idea of having the ‘eventual type’ at the start of the line (easier to see what’s going to happen eventually) I also like the idea of using the pipeline to show the ‘encapsulation flow’ of types within types (read to the end to see what happens).

A ‘hybrid’ style – ‘up-front’ when only one pipe would be required (e.g. Error exn) and pipeline otherwise (exn |> MyError |> Error), may also be an option.

I think I’ll probably end up ‘flip-flopping’ between different styles as I (hopefully) become more proficient in F# and eventually come up with a style that I like, maybe without realising that I’ve made a decision.