Haskell 可以用$替换圆括号吗?

Haskell 可以用$替换圆括号吗?,haskell,Haskell,我有以下功能: digits :: Int -> [Int] digits n = go n [] where go num acc | num < 10 = num : acc | otherwise = go (div num 10) (mod num 10 : acc) 数字::Int->[Int] 数字n=转到n[] 去哪里 |num

我有以下功能:

digits :: Int -> [Int]
digits n = go n []
    where go num acc
            | num < 10 = num : acc
            | otherwise = go (div num 10) (mod num 10 : acc)
数字::Int->[Int]
数字n=转到n[]
去哪里
|num<10=num:acc
|否则=通过(分区编号10)(模块编号10:acc)
是否可以将
表达式中的括号替换为
$

问题 你不能用
$
来做这个。
$
的目的是使函数应用程序尽可能轻松地绑定,这与绑定最紧密的普通函数应用程序不同

> :i $
($) :: (a -> b) -> a -> b
infixr 0 $
(一些不相关的东西被移除了…)

这里,
infixr
表示操作符是r右关联的,而
infixl
表示操作符是left关联的<代码>0
表示运算符的优先级
0
绑定最不紧密,而
9
绑定最紧密

如果我们编写
go$div num 10$mod num 10:acc
,这将被解释为
go(div num 10(mod num 10:acc))
,即:传递
mod num 10:acc
作为
div
的第三个参数,并将
div
作为
go
的唯一参数

解决方案:
(&)
操作符 左手边不用美元符号,
$
,而是可以使用
&

> :i &
(&) :: a -> (a -> b) -> b       -- Defined in `Data.Function'
infixl 1 &
现在我们得到:

import Data.Function ((&))

digits :: Int -> [Int]
digits n = go n []
    where go num acc
            | num < 10 = num : acc
            | otherwise = div num 10 & go $ mod num 10 : acc
在这种情况下,由于
(:)
也是中缀并且干扰
go
,因此需要右侧的括号

使用哪种解决方案 在我看来,如果您可以使用不带括号的中缀应用程序,请这样做。在任何一侧都有括号的情况下,例如:
divnum10`go`(mod num 10:acc)
,仍然可以保证使用中缀。这主要是由于可读性,因为一般读者可能不熟悉
&
。这个符号(可能)不是很常用,这就是为什么一般读者对它不是很熟悉(所以我们有一个循环…)

关于
$$

我相信Alexey Romanov的操作符,
$$
也很简洁。不幸的是,它遇到了与
相同的问题:不熟悉。希望他的操作符可以及时添加到
数据.函数中,也许我们可以扩展我们的工具箱。

除了@Centril提到的答案外,您只能替换第二对:

go (div num 10) $ mod num 10 : acc
或者两者都有,但您需要在不同的位置使用括号:

(go $ div num 10) $ mod num 10 : acc
或声明另一个操作符,如
$
,但左关联:

f $$ x = f x
infixl 0 $$

go $$ div num 10 $$ mod num 10 : acc

该操作符
$$
可以说比
&
,nice one=)更简洁。请注意,该算法只要求
divMod
,例如
go num=case divMod num 10 of(0,r)->[r];(q,r)->r:go q
。然而,这一点是正确的,它涉及到对算法的语义分析,而不是答案所讨论的更广泛、纯粹的语法分析。=)这只是一个额外的注释,而不是对你的答案的评论:)
f $$ x = f x
infixl 0 $$

go $$ div num 10 $$ mod num 10 : acc