类型同义词对类型类的实例有什么影响? GHC 中的 TypeSynonymInstances 编译指示有何作用?

2024-02-05

我正在阅读现实世界哈斯克尔第151页,我盯着下面这段话看了一个多小时:

回想一下,字符串是以下的同义词: [Char],它又是类型 [a] 其中 Char 替换为类型 参数a.根据 Haskell 98 的 规则,我们不允许提供 在以下情况下用类型代替类型参数 我们写一个实例。换句话说, 我们写一个是合法的 例如 [a],但不是 [Char]。 16 条评论 5335

它根本就没有被理解。盯着RWH 第 6 章的(免费非盗版)副本 http://book.realworldhaskell.org/read/using-typeclasses.html I see a lot其他人确实正在为此受苦。看了评论还是没看懂……

首先,关于这一切的一切都让我感到困惑,所以如果你觉得你可以解释一下这段话的任何内容,或者TypeSynonymInstances请这样做。

这是我的问题:

  • Int is a 数据构造器
  • String is a 数据构造器 AND 类型同义词

现在我无法回答这些问题:

  1. 为什么类型同义词会阻止使类型成为类型类的成员(我正在寻找可能与类型同义词的编译或实现相关的某种原因)?
  2. 为什么该语言的设计者不想要这种语法(我要求推理而不是广泛的理论或 unicode 数学符号)。
  3. 我看到这条线“类型 [a],其中 Char 替换类型参数 a”,我想知道为什么我不能用它来代替这个“类型 a,其中 Int 替换类型参数 a”.

Thanks!


我认为问题的部分原因在于两个基本上不相关的限制正在发挥作用:

  • 没有类型同义词实例意味着实例只能是用data or newtype, not type。这禁止String, 但不是[Char].
  • 没有灵活的实例意味着实例只能提及一种不是变量的类型,并且只有该类型可以用作类型构造函数。这禁止Maybe Int and f Int, 但不是Maybe a.

GHCi 是这样说的Int, Char, and String:

data Char = GHC.Types.C# GHC.Prim.Char#
data Int = GHC.Types.I# GHC.Prim.Int#
type String = [Char]

Int and Char都是没有类型变量参数的简单类型;不涉及类型构造函数,因此您可以非常自由地使用它们创建实例。

然而,字符串失败两者都很重要。这是一个类型同义词,这是不允许的,而且它也是一个应用于非变量的类型构造函数,即应用于Char的列表类型构造函数。

为了进行比较,请注意[a], Maybe a, and Either a b在实例中都有效,但是[Int], Maybe [a], and Either String a被禁止;希望您现在能明白原因。

至于你的直接问题,我不知道以这种方式设计语言的最初动机是什么,我也没有资格对“最佳实践”做出权威的陈述,但对于我自己的个人编码,我不这样做毫不犹豫地使用这些编译指示:

{-# LANGUAGE GeneralizedNewtypeDeriving #-}
{-# LANGUAGE EmptyDataDecls #-}
{-# LANGUAGE TypeSynonymInstances #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE FlexibleContexts #-}

你可以随时去看看。灵活的实例似乎确实得到了相当多的使用,并且来自“受人尊敬的”包(例如,Parsec 的源代码中有一些命中)。

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

类型同义词对类型类的实例有什么影响? GHC 中的 TypeSynonymInstances 编译指示有何作用? 的相关文章

  • 用于遇到 [...] 的 Haskell Parsec 解析器

    我正在尝试使用 Parsec 在 Haskell 中编写一个解析器 目前我有一个可以解析的程序 test x 1 2 3 end 执行此操作的代码如下 testParser do reserved test v lt identifier
  • QuickCheck是否可以生成任意函数

    我试图为身份编写一个 QuickCheck 测试 f y f y 我最初的计划是编写一个返回函数和整数的任意生成器 具有签名Gen Int gt Int Int 并在prop DollerDoesNothing使用 不使用测试该功能应用程序
  • 这个对自身单位的列表理解是如何工作的?

    在 haskell IRC 频道中有人问 是否有一种简洁的方法来定义一个列表 其中第 n 个条目是之前所有条目的平方和 我认为这听起来像一个有趣的谜题 递归定义无限列表是我真正需要练习的事情之一 所以我启动了 GHCi 并开始尝试递归定义
  • 在 monad 转换器类型类中使用列表 monad?

    我的目标是创建一个在 ReaderT WriterT 堆栈或 RWS 堆栈中使用列表 monad 的函数 更一般地说 如何在 mtl 类型类 例如 MonadReader MonadWriter 中使用列表 monad 我为什么要尝试这样做
  • 管道:多个流消费者

    我编写了一个程序来计算语料库中 NGram 的频率 我已经有一个函数 它消耗一串令牌并生成一个订单的 NGram ngram Monad m gt Int gt Conduit t m t trigrams ngram 3 countFre
  • 如何打乱列表?

    如何从一组数字 1 2 3 直到我击中x 我的计划是重新调整列表 1 2 3 并把它砍在x chopAt 3 2 3 1 2 3 chopAt 3 2 1 3 2 1 3 chopAt 3 3 1 2 3 chopAt chopAt x y
  • 迭代打印列表中的每个整数

    假设我有一个整数列表l 1 2 我想打印到stdout Doing print l产生 1 2 假设我想打印不带大括号的列表 map print l产生 No instance for Show IO arising from a use
  • 我是否需要采取明确的操作来促进与持久数据结构的共享?

    我来自命令式背景 正在尝试实现一个简单的不相交集 并集查找 数据结构 以获得在 Haskell 中创建和修改 持久 数据结构的一些练习 目标是有一个简单的实现 但我也关心效率 我的问题与此相关 首先 我创建了一个按等级并集的不相交集森林实现
  • 关于“没有绑定的类型签名”的错误

    我在 Haskell 中遇到 ASCII 问题 fromEnum Char gt Int toEnum Int gt Char offset Int offset fromEnum A fromEnum a toUpper Char gt
  • 如何在haskell中用另一个字符串替换一个字符串

    我想用不同的字符串替换输入文件中的字符串 我正在寻找一种方法 但似乎我只能逐个字符地更改字符串 例如在我下面的代码中 replace String gt String replace replace x xs if x then y rep
  • 使用带有两个列表而不是一个列表的地图。可以筑巢吗?

    我需要多次运行一个带有两个参数的函数 我有两个包含这些参数的列表 我希望能够使用map或类似的东西用相应的参数调用函数 我要调用的函数具有以下类型 runParseTest String gt String gt IO 列表的创建方式如下
  • 如何同时将透镜(或任何其他光学器件)视为吸气剂和设置剂?

    我正在尝试编写一个通用记录更新程序 它允许人们轻松更新记录中的字段existing记录 字段形状相似incoming记录 这是我到目前为止所拥有的 applyUpdater fields existing incoming let gett
  • 如何使用foldr为列表创建显示实例?

    我想为我的数据类型 我的列表 编写自己的显示实例 到目前为止 我的方法是有效的 但我总是在末尾有一个逗号 我已经尝试用最后一个元素启动折叠并将其从列表中删除 但它很麻烦而且不起作用 有没有更简单的方法来获得正确的解决方案 实际 1 2 3
  • 为什么我不能声明推断类型?

    我有以下内容 runcount Eq a Num b gt a gt b runcount runcountacc 0 runcountacc Eq a Num b gt b gt a gt b runcountacc n runcount
  • 检索 Haskell 项目中所有导入的列表

    因此 我的最终目标是通过确保项目导入的所有实体都存在于其声称可以使用的版本中 来评估 cabal 文件中依赖项的准确性 一个好的开始是找到单个源文件使用的所有导入实体的列表 可选地包含有关它们来自何处的信息 我愿意暂时忽略类实例的情况 因为
  • 在 Archlinux 上使用 Vim 作为 Haskell 的 IDE 目前情况如何?

    如果可行的话 我的目标是通过 YouCompleteMe 在 Vim 中完成 Haskell 的命令 在这方面 正如您在下面看到的 我还没有找到关于如何让它发挥作用的共识 相关评论的最新评论YouCompleteMe 上的问题 https
  • 如何使用类型系统编码和强制执行合法的 FSM 状态转换?

    假设我有一个类型Thing拥有国有财产A B C 合法的状态转换是A gt B A gt C C gt A 我可以写 transitionToA Thing gt Maybe Thing 这会返回Nothing if Thing处于无法转换
  • 类型类实例化中的现有常量(例如构造函数)

    考虑这个伊莎贝尔代码 theory Scratch imports Main begin datatype Expr Const nat Plus Expr Expr 实例化是相当合理的plus输入 class 以获得良好的语法Plus构造
  • Haskell 为替代的 Either 数据类型定义 Functor 实例

    通过 Typeclassopedia 获得一些使用类型类的路由 想要替代Either的一个实例Functor 但即使检查定义Either作为一个例子Functor总是给我带来麻烦 有这个 但不会编译 data Alt a b Success
  • Cabal 无法安装依赖项,但如果直接询问可以安装它们

    我发现 Cabal 反复出现一个非常奇怪的问题 它影响了我获得可重复的 Haskell 构建的能力 我有一个带有沙箱的阴谋集团项目 如果我做cabal install 我收到以下形式的错误 Y failed during the build

随机推荐