我是函数式编程的新手,我尝试使用Haskell创建和显示Stack。我希望我的程序能够向我展示Stack I&#m; m with building。这是我的代码:
module Stack (Stack, empty, push, pop, top, isEmpty) where
data Stack a = EmptyStack | Stk a (Stack a)
push x s = Stk x s
top (Stk x s) = x
pop (Stk _ s) = s
empty = EmptyStack
isEmpty EmptyStack = True
isEmpty (Stk x s) = False`
instance Show a => Show (Stack a) where
show EmptyStack = "|"
show (Stk a b) = (show a) ++ " <- " ++ (show b)
用&#34;显示(按1空)&#34;我希望答案(或多或少)像:&#34; 1&lt; - | &#34; 但是我无法编译代码。当我尝试它时显示以下错误:
[1 of 1] Compiling Stack ( Stack.hs, interpreted )
Stack.hs:12:27:
Ambiguous occurrence ‘show’
It could refer to either ‘Stack.show’, defined at Stack.hs:11:9
or ‘Prelude.show’,
imported from ‘Prelude’ at Stack.hs:1:8-12
(and originally defined in ‘GHC.Show’)
Stack.hs:12:47:
Ambiguous occurrence ‘show’
It could refer to either ‘Stack.show’, defined at Stack.hs:11:9
or ‘Prelude.show’,
imported from ‘Prelude’ at Stack.hs:1:8-12
(and originally defined in ‘GHC.Show’)
Failed, modules loaded: none.
我理解程序可能会混淆&#34; show&#34;来自Prelude的&#34; show&#34;由be定义,但我在代码中看不到该错误。此外,一些配偶具有相同的代码,程序运行良好。
我有什么需要改变或者我错过了吗?
谢谢!
答案 0 :(得分:1)
所以第一个问题是你为我们粘贴的代码中有一个`
字符。你的第二个问题是你不需要缩进模块中的所有行;我看到的大多数Haskell模块将不缩进模块的主体。你的第三个问题是你不需要在show a
和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 }
所以多重定义被正确地转换为case-dispatch,但它并没有放在上面的花括号中!因此,您可以通过使用空格来缩进行来省略花括号{}
。在where
之后,Haskell看不到任何显式的{}
,所以它开始寻找缩进的行,并且它看到0,所以它将子句转换为where {}
(感谢@chi)。
由于缩进与否,没有大括号,新行定义了一个不同的函数Stack.show
,不同于属于Prelude.show
类型类的导入的Show
。问题是它还引用了一个名为show
的函数,它现在是不明确的:这是对具有无限类型show :: Stack (Stack (Stack ...)) -> String
或调度的函数的递归调用调用有限类型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
子句。