所以第一个问题是你有一个`
您为我们粘贴的代码中的字符。第二个问题是您不需要缩进模块中的所有行;我看到的大多数 Haskell 模块都会not缩进模块的主体。你的第三个问题是你不需要括号show a
and show b
:Haskell 中的优先级非常简单;括号始终具有最高优先级,然后是函数应用程序(左关联或“贪婪名词”,函数总是吞噬它前面看到的第一个东西),然后是按其定义的优先级排列的运算符,然后是特殊的语法形式喜欢\a ->
, let
, do
, where
。这些通常是审美问题,但您可能仍然关心。
你的最后一个问题在这里:
instance Show a => Show (Stack a) where
show EmptyStack = "|"
show (Stk a b) = (show a) ++ " <- " ++ (show b)
您希望 Haskell 将其转换为单个语句:
instance Show a => Show (Stack a) where show tmpvar = case tmpvar of { EmptyStack -> "|"; Stk a b -> show a ++ " <- " ++ show b }
然而 Haskell 将其变成了两行:
instance Show a => Show (Stack a) where {}
show tmpvar = case tmpvar of { EmptyStack -> "|"; Stk a b -> show a ++ " <- " ++ show b }
因此,多重定义已正确转换为案例调度,但它没有放在上面的花括号内!所以,你可以省略花括号{}
通过使用空格来缩进行。后where
, Haskell 没有看到任何明确的{}
所以它开始寻找缩进行,它看到其中 0 个,所以它将子句转换为where {}
(谢谢@chi)。
没有在花括号中,无论是否因为缩进,该新行定义了一个不同的函数,Stack.show
,与进口的不同Prelude.show
属于Show
类型类。问题是它还引用了一个名为show
,现在是不明确的:这是一个递归的调用无限类型的函数show :: Stack (Stack (Stack ...)) -> String
or a 调度调用有限类型的函数show :: (Show a) => Stack a -> String
?在它试图找出这些类型之前,它会说“停下来,我不知道你的意思,请澄清一下。”
也许你的意图是:
instance Show a => Show (Stack a) where
show EmptyStack = "|"
show (Stk a b) = show a ++ " <- " ++ show b
这个缩进提示 Haskell 编译器将以下两个语句接受到where
clause.