Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Right associative operator in F# [duplicate]

Tags:

f#

Sometimes I have to write:

myList |> List.iter (fun x -> x)

I would really like to avoid the parentheses. In Haskell there is an operator for this ($)

It would look like this

myList |> List.iter $ fun x -> x

I created a custom operator

let inline (^!) f a = f a

and now I can write it like this

myList |> List.iter ^! fun x -> x

Is there something like this in F#?

like image 490
Maik Klein Avatar asked Dec 09 '22 10:12

Maik Klein


2 Answers

There is no way to define custom operator with an explicitly specified associativity in F# - the associativity is determined based on the symbols forming the operator (and you can find it in the MSDN documentation for operators).

In this case, F# does not have any built-in operator that would let you avoid the parentheses and the idiomatic way is to write the code as you write it originally, with parentheses:

myList |> List.iter (fun x -> x)

This is difference in style if you are coming from Haskell, but I do not see any real disadvantage of writing the parentheses - it is just a matter of style that you'll get used to after writing F# for some time. If you want to avoid parentheses (e.g. to write a nice DSL), then you can always named function and write something like:

myList |> List.iter id

(I understand that your example is really just an example, so id would not work for your real use case, but you can always define your own functions if that makes the code more readable).

like image 71
Tomas Petricek Avatar answered Dec 11 '22 00:12

Tomas Petricek


No, there's nothing like this in a standard F# library. However, you have almost done creating your own operator (by figuring out its name must start with ^).

This snippet by Stephen Swensen demonstrates a high precedence, right associative backward pipe, (^<|).

let inline (^<|) f a = f a

This single-liner from the linked page demonstrates how to use it:

{1..10} |> Seq.map ^<| fun x -> x + 3

And here is an example how to use it for multi-line functions. I find it most useful for real-world multi-liners as you no longer need to keep closing parenthesis at the end:

myList
|> List.map
    ^<| fun x ->
        let ...
        returnValue
like image 36
bytebuster Avatar answered Dec 10 '22 23:12

bytebuster