当我在输入中得到解析错误时,如何在Haskell中使用(@)运算符?

当我在输入中得到解析错误时,如何在Haskell中使用(@)运算符?,haskell,Haskell,我是Haskell的新手,我正在尝试计算最大段和 (@) :: Int -> Int -> Int x @ y = 0 `max` (x + y) mss2 :: [Int] -> Int mss2 = maximum . scanr (@) 0 错误是 没有为(@)加载模块 我在Richard Bird的文本中找到了这个片段。 我错过了什么? 有没有其他方法来声明/重载运算符,我的方法错了吗?在那本书的上下文中,(@)似乎被用作某些二进制运算符的替代,例如(+)或(),尽

我是Haskell的新手,我正在尝试计算最大段和

(@) :: Int -> Int -> Int
x @ y = 0 `max` (x + y)

mss2 :: [Int] -> Int
mss2 = maximum . scanr (@) 0
错误是

没有为(@)加载模块

我在Richard Bird的文本中找到了这个片段。 我错过了什么?
有没有其他方法来声明/重载运算符,我的方法错了吗?

在那本书的上下文中,
(@)
似乎被用作某些二进制运算符的替代,例如
(+)
()
,尽管这实际上不是合法的Haskell语法†

有关Haskell语法的问题,请参考

在第2章词汇结构中,在下,您可以在运算符名称中可能出现的符号语法中找到
@

象征→ ascSymbol |统一符号⟨特殊的|
|
|
⟩ ascSymbol→ <代码>!
$
%
&
+

|
\
^
-
~
并定义有效的运算符名称以包括以下符号:

瓦尔西姆→ (符号⟨<代码>:
⟩ {符号})⟨保留短划线⟩ 同性→ (
{符号})⟨储备⟩ 但是,尖括号中的下标表示“差异”或排除,因此不允许保留标识符列表。在production reservedop下,您可以发现该列表中出现了
@

储备→ <代码>。
=

原因是
@
符号表示“as”模式,如中所述:

  • 匹配as模式var@apatv值是将apat与v相匹配的结果,并通过var与v的结合得到增强
  • 因为模式对于控制值共享和使某些定义更简洁非常有用,例如:

    -- | Merge two sorted lists.
    merge :: (Ord a) => [a] -> [a] -> [a]
    
    -- ‘as0’ & ‘bs0’ denote the original input lists.
    -- ‘as’ & ‘bs’ denote their tails.
    
    merge as0@(a : as) bs0@(b : bs) = case compare a b of
    
      -- ‘as0’ passes along the same list cell;
      -- repeating ‘a : as’ would allocate a /new/ cell.
    
      GT -> b : merge as0 bs
      _  -> a : merge as  bs0
    
    merge [] bs0 = bs0
    merge as0 [] = as0
    
    因此,定义:

    x @ y = 0 `max` (x + y)
    
    或更常规地编写
    x@y=…
    ,相当于定义两个引用相同值的变量,并且递归定义:

    x = 0 `max` (x + y)
    y = x
    
    如果没有类型签名
    Int->Int->Int
    ,将接受此定义,定义
    x,y:(Ord a,Num a)=>a
    ,但尝试计算任一变量将产生无限循环,因为这是“非生产性”递归

    解决方案是使用非保留符号作为操作员名称,例如
    +。


    †我找不到这方面的引文,但GHC可能曾经接受这种语法,尽管在本书第一版出版时,这种语法也被现行的语法所禁止,而且这个示例代码只是没有更新到第二版。

    x@y=…
    并不意味着你认为它有什么作用s、
    @
    被用作,而不是中缀运算符。请尝试使用
    x[a,b]=[1,2]
    ,然后选中
    x
    a
    b
    。是的,
    @
    实际上是一个保留符号。(例如,它在高级Haskell中具有“类型应用”的特殊效果。)我不会尝试将其用作普通运算符。我尝试了上述函数,而不是
    @
    ,我使用了
    $
    ,将其隐藏在原始实现中,效果很好。因此这意味着
    @
    不是普通运算符。感谢您的帮助@Brian和@AntCYou也可以尝试
    @
    @
    @
    或其他一些变体,但
    @
    是保留符号之一,如与相关的
    ->