F# 中的 Haskell `$` 可能吗?

Smo*_*Ken 5 f# haskell operator-overloading binary-operators

在 Haskell 中,我们可以写

print $ abs $ 3 - 5

使用$

在 F# 中,我们可以这样写

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

然而,在 F# 中的许多情况下,具有相同的功能也很有用,$因为上面只是带有二元运算符的表达式。

Haskell 的技巧$是它的二元运算符中优先级最低。

于是我又调查了一下

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

不幸的是,我观察到,没有优先级较低的运算符可以安全地重载,因为它们似乎都是必不可少的。

您对此有什么想法吗?

你认为$F# 中的 Haskell 可能吗?

lef*_*out 9

与 Haskell 一样,F\xe2\x99\xaf 还允许您定义新的中缀运算符,而不仅仅是重载现有的中缀运算符。然而,与 Haskell 不同的是,您不能随意选择优先级(也称为固定性),也不能选择任何非字母 Unicode 符号。相反,您必须从!, $, %, &, *, +, -, ., /, <, =, >, ?, @, ^,中进行选择|。然后通过与标准运算符进行类比来确定固定性,以一种我不完全理解的方式,但似乎确实是这样的,对于任何单符号中缀,您可以通过添加一个具有相同固定性的自定义符号.在前。

\n

因此,要获得固定性最低的运算符,您必须将其称为.|. 然而,|是左关联的,所以你不能写printfn "%d" .| abs .| 3 - 5. 不过我注意到,在 Haskell 中,你的示例也更愿意写成print . abs $ 3 - 5,并且确实可以用 F\xe2\x99\xaf 来表达:

\n\n
let (.|) f x = f x\nprintfn "%d" << abs .| 3 - 5\n
Run Code Online (Sandbox Code Playgroud)\n

要音译print $ abs $ 3 - 5,您需要一个关联运算符。我可以定义的最低优先级自定义右关联运算符是.^,这确实使示例正常工作:

\n
let (.^) f x = f x\nprintfn "%d" .^ abs .^ 3 - 5\n
Run Code Online (Sandbox Code Playgroud)\n

然而,这个运算符的优先级并不是很低,特别是它实际上比复合运算符具有更高的优先级!

\n
\n

实际上,您不应该这样做,而应该按照printfn "%d" << abs <| 3 - 5您最初的建议使用。它是标准的,也符合 Haskell 中的首选样式。

\n