Haskell 中“show”出现歧义

2023-12-21

我是函数式编程的新手,我正在尝试使用 Haskell 创建并展示堆栈。我希望我的程序能够向我展示我正在用它构建的堆栈。这是我的代码:

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)

对于“show (push 1 empty)”,我希望得到一个答案(或多或少),例如:“ 1

[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.

我理解程序可能会将 Prelude 中的“show”与 be 定义的“show”混淆的错误,但我在代码中看不到该错误。另外,有些朋友有相同的代码,程序运行得很好。

有什么我必须改变或者我错过了的吗?

Thanks!


所以第一个问题是你有一个`您为我们粘贴的代码中的字符。第二个问题是您不需要缩进模块中的所有行;我看到的大多数 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.

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Haskell 中“show”出现歧义 的相关文章

随机推荐

  • PyDev 控制台工作目录

    当我打开 PyDev 控制台时 当前工作目录是我的 Eclipse 文件夹 如何配置控制台以使用项目文件夹作为当前工作目录 可以在工作区范围内设置吗 这个问题 https stackoverflow com questions 103199
  • Drupal:添加新节点时自动添加菜单项

    在Drupal中向页面添加节点时可以自动添加菜单项吗 换句话说 我可以将菜单父级与节点内容类型相关联 然后在添加新节点时自动添加子级吗 thanks 您可以使用 Drupal 7 上的规则来完成此操作 该模块 http drupal org
  • 为什么“删除[][]...多维数组;” C++中不存在运算符

    我一直想知道标准C 语言中是否有删除多维数组的运算符 如果我们创建了一个指向一维数组的指针 int array new int size 删除看起来像 delete array 那太棒了 但是如果我们有二维数组 我们就不能这样做 delet
  • python导入语句

    我已经开始使用 Python 大约一个月了 我遇到了一些我想更好地理解的事情 跟进口有关系 所以我有一个模块 根 核心 连接性 现在在这个模块中我定义了一个类 Connectivity 该模块还有一个 main 仅用于测试目的 不确定这是否
  • MYSQL - 将数据拆分为多行

    我使用一个应用程序导入了一些数据 该应用程序从 IMDB 收集信息并将其传输到 MYSQL 数据库中 这些字段似乎尚未标准化 并且 1 个字段中包含许多值 例如 Table Movie MovieID Movie Title Written
  • 删除div之间的空白

    我在两个 div 之间发现了一些奇怪的空白 每个div都有css属性display inline block每个都有固定的高度和宽度 我找不到空白在哪里 这是一个小提琴 http jsfiddle net RVAQp 1 那里有空格 因为
  • 如何使用 TypeScript 从 npm 扩展模块?

    我在用着joi https github com hapijs joi blob master API md and 类型 joi https github com DefinitelyTyped DefinitelyTyped tree
  • 无法获得 D-Bus 连接:不允许操作

    我正在尝试在 docker centos7 映像上安装 ambari 2 6 但在 ambari 设置步骤中以及在初始化 postgresql 数据库时 我收到此错误 无法获得 D Bus 连接 不允许操作 每次我尝试在 Docker 映像
  • swagger 正在添加上下文根两次

    我正在使用 swagger 3 0 0 SNAPSHOT 和 spring data rest 我的应用程序属性文件中有上下文配置 server servlet context path sample 我的swagger配置如下 Confi
  • 在 DataGridTemplateColumn 内的 TextBlock 上复制 ContextMenu 上的命令

    想问一下 因为以前从未在 TextBlock 上这样做过 我无法复制 DataGridTemplateColumn 的内容 其中有一个 TextBlock 并且我已为其分配了一个上下文菜单 复制的内容是空白的 当我在 MS Word 中尝试
  • Python BeautifulSoup:解析具有相同类名的多个表

    我正在尝试解析 wiki 页面中的一些表格 例如http en wikipedia org wiki List of Bollywood films of 2014 http en wikipedia org wiki List of Bo
  • 如何在不使用异常的情况下检查 constructor() 中的失败?

    我正在处理的所有类都有 Create Destroy 或 Initialize Finalized 方法 Create 方法的返回值为bool像下面这样 bool MyClass Create 所以我可以从返回值中检查实例的初始化是否成功
  • Aeson:将动态键解析为类型字段

    假设有一个像这样的 JSON bob id name bob age 20 jack id name jack age 25 是否可以将其解析为 Person with Person定义如下 data Person Person id Te
  • php 正则表达式 utf-8 中的单词边界匹配

    我在 utf 8 php 文件中有以下 php 代码 var dump setlocale LC CTYPE de DE utf8 German Germany utf 8 de DE german var dump mb internal
  • 如何定义常量值 - 最佳实践

    我有两种定义常量的方法 第一个在类中保存一堆静态最终 DataType 变量 另一个使用 Enum 这是拳头类型 public class TipTipProperties public static final String MAX WI
  • 动态创建 QML ListElement 和内容

    所以我试图在 a 中动态创建 ListElementsListModel 在我尝试在 ListElements 中写入一些要动态加载的内容之前 这种方法工作得很好 我尝试用以下命令创建一个自己的文件ListElement在 和 小时内作为属
  • Jackson:名称为“defaultReference”的多个反向引用属性

    我正在尝试将 json 字符串格式 映射到对象 但出现以下错误 com fasterxml jackson databind JsonMappingException 多个 名称为 defaultReference 的反向引用属性 这是 j
  • 静态地图:绘制具有多个点的多边形。 (2048 个字符限制)

    由于 get 请求中存在 2048 个字符的限制 因此您无法使用 Google Static Maps 生成包含具有大量多边形点的多边形的图像 特别是当您尝试在一张地图上绘制许多复杂的多边形时 如果您使用 Google Maps API 那
  • php 脚本查找 Web 服务器名称

    是否有任何 php 脚本可以查找 Web 服务器的名称 例如 apache varnish nginx 等 我了解 netcraft 和 wappalyzer 但我想要一个脚本在我的本地计算机上运行 主要原因是 我的本地机器中有4台服务器A
  • Haskell 中“show”出现歧义

    我是函数式编程的新手 我正在尝试使用 Haskell 创建并展示堆栈 我希望我的程序能够向我展示我正在用它构建的堆栈 这是我的代码 module Stack Stack empty push pop top isEmpty where da