我有以下功能:
digits :: Int -> [Int]
digits n = go n []
where go num acc
| num < 10 = num : acc
| otherwise = go (div num 10) (mod num 10 : acc)
Run Code Online (Sandbox Code Playgroud)
是否可以用otherwise表达式替换括号中的括号$?
你无法使用$它.目的$是使函数应用程序尽可能无法绑定,而不是绑定最紧密的正常函数应用程序,
> :i $
($) :: (a -> b) -> a -> b
infixr 0 $
Run Code Online (Sandbox Code Playgroud)
(删除了一些不相关的东西......)
这里,infixr表示该操作者是- [R飞行关联,而不是infixl其表示操作者是升 EFT关联.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 &
Run Code Online (Sandbox Code Playgroud)
现在我们得到:
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
Run Code Online (Sandbox Code Playgroud)
go缀你也可以使用中go缀:
digits :: Int -> [Int]
digits n = go n []
where go num acc
| num < 10 = num : acc
| otherwise = div num 10 `go` (mod num 10 : acc)
Run Code Online (Sandbox Code Playgroud)
在这种情况下,需要右侧的括号,因为(:)它也是中缀和干扰go.
在我看来,如果你可以使用没有括号的中缀应用程序,那就这样做吧.如果在任何一方使用括号,例如:in div num 10 `go` (mod num 10 : acc),则仍然需要使用中缀.这主要是由于可读性,因为普通读者可能不熟悉&.这种表示法(可能)并不常用,这就是为什么普通读者不熟悉它(因此我们有一个循环......).
$$我相信阿列克谢罗曼诺夫的运营商,$$也很整洁.不幸的是,它遇到了同样的问题&:缺乏熟悉度.希望他的操作员可以Data.Function在适当的时候添加,也许我们可以扩展我们的工具箱.
除了@Centril提到的答案之外,你只能替换第二对:
go (div num 10) $ mod num 10 : acc
Run Code Online (Sandbox Code Playgroud)
或者两者兼而有之,但是你需要在不同的地方括号:
(go $ div num 10) $ mod num 10 : acc
Run Code Online (Sandbox Code Playgroud)
或声明另一个运算符,$但左关联:
f $$ x = f x
infixl 0 $$
go $$ div num 10 $$ mod num 10 : acc
Run Code Online (Sandbox Code Playgroud)