Home > Net >  Haskell `$` in F# possible?
Haskell `$` in F# possible?

Time:09-08

In Haskell, we can write

print $ abs $ 3 - 5

using $ .

In F#, we can write

printfn "%d" << abs <| 3 - 5

However, in many cases in F#, it would be also useful to have the same functionality of $ since the above are simply expressions with binary operators.

The trick of Haskell $ is that has somewhat the lowest precedence among its binary operators.

So, I investigated again

https://docs.microsoft.com/en-us/dotnet/fsharp/language-reference/symbol-and-operator-reference/#operator-precedence

and I observe, unfortunately, that there are no operators in lower precedences that can overload safely because all of them seem essential.

Do you have any ideas on this?

Do you think Haskell $ in F# is possible??

CodePudding user response:

Like Haskell, F♯ also allows you to define new infix operators, not just overload existing ones. Unlike Haskell however, you can't select precedence (aka fixity) at will, nor select any non-letter Unicode symbol. Instead, you must choose from !, $, %, &, *, , -, ., /, <, =, >, ?, @, ^, |. The fixity is then determined by analogy with the standard operators, in a way I don't entirely understand but what does seem to hold is that for any single-symbol infix, you can make a custom one with the same fixity by adding a . in front.

So, to get a lowest-fixity operator you'd have to call it .|. However, | is left-associative, so you couldn't write printfn "%d" .| abs .| 3 - 5. However I'd note that in Haskell, your example would also rather be written print . abs $ 3 - 5, and that can indeed be expressed in F♯:

let (.|) f x = f x
printfn "%d" << abs .| 3 - 5

To transliterate print $ abs $ 3 - 5, you'd need a right-associative operator. The lowest-precedence custom right-associative operator I can manage to define is .^, which indeed gets the example working:

let (.^) f x = f x
printfn "%d" .^ abs .^ 3 - 5

However, this operator doesn't have very low precedence, in particular it actually has higher precedence than the composition operators!


Really, you shouldn't be doing any of this and instead just use printfn "%d" << abs <| 3 - 5 as you originally suggested. It's standard, and it also corresponds to the preferred style in Haskell.

  • Related