在下面的代码中,fibseq表示来自Fibonacci序列的数字序列.(从代码中解决Project Euler#2)
我已经定义了一个中缀函数|>:
(|>) x y = y x.
Run Code Online (Sandbox Code Playgroud)
这让我可以执行以下操作(如unix管道):
take 34 fibseq |> filter even |> filter (< 4000000) |> sum
Run Code Online (Sandbox Code Playgroud)
我的问题是,为什么这有效?
我本以为 take 34 fibseq |> filter even应该转换成filter (take 34 fibseq) even,(我认为)会导致类型错误.
相反,它似乎正在转变为filter even (take 34 fibseq)哪些作品并且是我想要的,但我不明白它为什么会起作用.
sth*_*sth 24
函数应用程序(filter even比)比任何运算符都更紧密,所以你的代码相当于:
(take 34 fibseq) |> (filter even) |> (filter (< 4000000)) |> sum
Run Code Online (Sandbox Code Playgroud)
这是因为运算符优先级.函数应用程序运算符,并置或 (the space), has the highest precedence, so take 34 fibseq |> filter even解析为((take 34) fibseq) |> (filter even),相当于(filter even) ((take 34) fibseq); 因为函数应用程序是左关联的,所以这相当于filter even (take 34 fibseq).
通常,任何二元运算符都可以优先使用固定性声明,例如
infixl 0 |>
infixr 9 .
Run Code Online (Sandbox Code Playgroud)
的l或r说,操作是否是左或右结合(即,是否a • b • c团作为(a • b) • c或a • (b • c)); number - 0到9之间的整数 - 指定优先级.数字越大意味着优先级越高(应用程序的有效优先级为∞); 例如,*和/具有优先权7,和+与-具有优先权6.要检查在ghci中操作者的优先级,只需要输入:info $(或无论哪个操作者)在提示.
并且作为一个注释:您的代码将起作用,但这不是我通常会编写它的方式.如果你很好奇,在Haskell中,我会用$运算符编写代码,运算符只执行函数应用但优先级低:filter even $ take 34 fibseq.如果我有更多的函数要应用,我会使用合成运算符:fun1 arg1 . fun2 . fun3 arg2 arg3 . filter even $ take 34 fibseq.它以另一种方式读取,但它通常是您在Haskell中找到的.
| 归档时间: |
|
| 查看次数: |
4158 次 |
| 最近记录: |