空格是否用作函数应用程序运算符或单词分隔符

时间:2019-07-15 01:01:49

标签: haskell

How does outermost evaluation work on an application of a curried function?说:

  

在Haskell中,空格是一个运算符:它将lhs函数应用于rhs参数。

是真的吗?我在文档中找不到它。

当Haskell编译器用词法分析Haskell程序时,空白被识别为函数应用程序运算符还是令牌分隔符?

谢谢。

2 个答案:

答案 0 :(得分:8)

我以前从未听过有人说空格是运算符。我想您可以在函数应用程序的上下文中将其视为运算符,但在大多数情况下,它不是运算符。例如,在以下代码示例中,我看不到将空格视为运算符的任何方式,其中空格仅用于分隔令牌:

module Main where

x = "test 1"
y = "test 2"

main = do
    (z : zs) <- getLine
    putStrLn $ z : (x ++ y ++ zs)

在这里看起来很明显,空白纯粹是作为令牌分隔符。最好将f x y z之类的明显的“操作符”理解为是说,如果两个值彼此相邻放置,则第二个将应用于第一个。例如,putStrLn"xxx"putStrLn "xxx"都将"xxx"应用于putStrLn;空间完全无关紧要。

编辑:在评论中,@ DanielWagner提供了两个很好的示例。首先,(f)xf x相同,但没有空格;在这里,我们可以确认该空间纯粹是用作标记分隔符,因此可以用方括号(也分隔标记)代替,而不会影响表达式的词素。其次,f {x=y}不会将{x=y}应用于f,而是使用记录语法基于f创建新记录;再次,我们可以删除空格以获取f{x=y},这对分离词素同样起到了很好的作用。

答案 1 :(得分:1)

在大多数情况下,空白是“函数应用程序”,这意味着将右边的函数应用于左边的参数,就像($)运算符一样,但是可以在使用时更加清楚您的代码,例如:

plusOne = (1 +)

你可以做

plusOne 2

plusOne $ 2

:t ($)
($) :: (a -> b) -> a -> b

我忘记了一个有用的例子:

想象一下,要过滤大于3的值,但要在每个元素上添加一个值:

filter (>3) $ map plusOne [1,2,3,4]

可以编译,但是不会:

filter (>3) map plusOne [1,2,3,4]

但是在其他情况下,它不是函数应用程序,就像其他@bradrn答案或@Daniel warner注释一样。