类型类是必需的吗?

2024-03-02

我曾经问过一个问题哈斯克尔初学者 https://groups.google.com/forum/#!topic/haskell-cafe/C1zGMkYGTOY,是否使用 data/newtype 还是类型类。在我的特殊情况下,事实证明不需要类型类。此外,汤姆·埃利斯(Tom Ellis)给了我一个绝妙的建议,当我有疑问时该怎么做:

回答这个问题最简单也是最正确的方法是:

使用数据

我知道类型类可以让一些东西变得更漂亮,但没多大作用。让我印象深刻的是,类型类主要用于脑干的东西,而在较新的东西中,新的类型类几乎不会被引入,一切都是通过 data/newtype 完成的。

现在我想知道是否存在绝对需要类型类而无法用 data/newtype 表达事物的情况?

回答类似问题堆栈溢出 https://stackoverflow.com/questions/17100036/should-i-use-typeclasses-or-not加布里埃尔·冈萨雷斯说

在以下情况下使用类型类:

每种给定类型只有一种正确的行为

类型类具有所有实例都必须满足的关联方程(即“定律”)

Hmm ..

或者类型类和数据/新类型是否由于历史原因而共存,有些相互竞争的概念?


我认为类型类areHaskell 的重要组成部分。

它们是 Haskell 的一部分,使其成为我所知道的最容易重构的语言,并且它们对于您能够推断代码的正确性来说是一笔巨大的财富。

那么,我们来谈谈字典传递。

现在,任何类型的字典传递都是对传统面向对象语言的状况的重大改进。我们知道如何在 C++ 中使用 vtable 进行 OOP。然而,在 OOP 语言中,vtable 是“对象的一部分”。将 vtable 与对象融合会迫使你的代码变成一种形式,在这种形式中,你对谁可以用新功能扩展核心类型有严格的纪律,实际上只有类的原始作者必须将其他人想要融入的所有东西结合起来他们的类型。这导致了“熔岩流代码”和各种其他设计反模式等。

像 C# 这样的语言让你能够侵入扩展方法来伪造新的东西,而 scala 等语言的“特征”和其他语言的多重继承也让你可以委托一些工作,但它们只是部分解决方案。

当你将 vtable 从它们操作的对象中分离出来时,你会得到一股令人兴奋的力量。现在您可以将它们传递到任何您想要的地方,但是当然您需要命名它们并谈论它们。围绕模块/函子的 ML 规则和显式字典传递风格采用了这种方法。

类型类采取稍微不同的策略。我们依赖于给定类型的类型类实例的唯一性,并且主要是这种选择,它允许我们摆脱这种简单的核心数据类型。

Why?

因为我们可以将字典的使用转移到使用站点,而不必将它们与数据类型一起携带我们可以相信,当我们这样做时,代码的行为没有任何改变.

将代码机械翻译为更复杂的手动传递的字典会失去此类字典在给定类型下的唯一性。现在,在程序的不同点传递字典会导致程序具有截然不同的行为。您可能需要也可能不需要记住构造您的数据类型所用的字典,如果您想根据您的参数进行条件行为,那么您将遭遇不幸。

对于简单的例子,例如Set您可以通过手动词典翻译来摆脱困境。价格好像没那么高。你必须在字典中烘焙,比如说,你想如何排序Set当你制作这个物体然后insert/lookup,只会保留您的选择。这可能是你可以承受的成本。当你联合两个Set当然,现在您收到的订单还是悬而未决的。也许你把较小的插入到较大的中,但是顺序会随意改变,所以你必须把左边的插入到右边,或者记录这种随意的行为。为了“灵活性”,您现在被迫采用性能不佳的解决方案。

But Set这是一个简单的例子。在那里,您可以将索引烘焙到有关您正在使用的实例的类型中,只涉及一个类。当您想要更复杂的行为时会发生什么?我们用 Haskell 做的事情之一就是使用 monad 转换器。现在你有lots大量的实例漂浮在周围——而你没有一个好的地方来存储它们,MonadReader, MonadWriter, MonadState等等都可以根据底层 monad 有条件地应用。当您吊起并更换它时会发生什么,现在不同的事情可能适用或可能不适用?

为此携带显式字典需要大量工作,没有一个好的地方来存储它们,并且您要求用户采用全局程序转换来采用这种做法。

这些都是类型类可以轻松完成的事情。

我相信你应该将它们用于所有事情吗?

不是由一个长镜头。

但我不同意这里的其他回复,认为它们对 Haskell 来说是无关紧要的。

Haskell 是唯一提供它们的语言,并且它们至少对于my用这种语言思考的能力,这是我将 Haskell 视为家的一个重要原因。

我确实同意这里的一些事情,当有法律并且选择明确时使用类型类。

然而,我会质疑,如果你没有法律或者选择不明确,你可能对如何建模问题域了解不够,并且应该寻找你想要的东西can将其放入类型类模型中,甚至可能放入现有的抽象中——当您最终找到该解决方案时,您会发现可以轻松地重用它。

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

类型类是必需的吗? 的相关文章

  • 一个目录中的多个 Haskell cabal-packages

    在一个目录中包含多个 cabal 软件包的推荐方法是什么 Why 我有一个包含许多可分离模块的旧项目 由于最初它们只形成一个程序 因此将它们放在同一目录中以便于编译非常方便 而且现在仍然如此 Options 只是忍受并将所有内容 包括保存内
  • Haskell - 交替两个列表中的元素

    我正在尝试编写一个 haskell 函数 它接受两个整数列表并生成一个列表 其中包含从两个列表中交替获取的元素 我有这个功能 blend xs ys 一个例子 blend 1 2 3 4 5 6 应该返回 1 4 2 5 3 6 我的逻辑是
  • 如何使用 alex/haskell 执行 python 风格的缩进/缩进标记?

    我正在用 Haskell 为 Alex 中的一种小语言编写一个词法分析器 该语言被指定为具有 python 式的显着缩进 只要缩进级别发生变化 就会发出 INDENT 标记或 DEDENT 标记 在像 C 这样的传统命令式语言中 您将在词法
  • 测试列表是否已排序

    在 haskell 中找到最小列表确实很容易 foldl1 min 9 5 7 3 7 4 6 10 给我3 我更换了min with lt 测试列表是否已排序 foldl1 lt 9 5 7 3 7 4 6 10 我收到此错误消息 No
  • 结构上强制的自由替代,没有左派分配性

    有一个不错的免费替代品 http hackage haskell org package free 4 12 4 docs Control Alternative Free html在伟大的free包 它将函子提升到左分配替代方案 也就是说
  • 哈斯克尔状态单子

    是否putState Monad 的函数会更新实际状态还是仅返回具有新值的新状态 我的问题是 State Monad 可以在命令式设置中像 全局变量 一样使用吗 并且确实put修改 全局变量 我的理解是 不 它不会修改初始状态 但是使用单子
  • 我是否应该使用 GHC Haskell 扩展?

    当我学习 Haskell 时 我发现有很多语言扩展 http haskell org ghc docs latest html users guide ghc language features html在现实生活中使用的代码 作为初学者
  • 当单态限制打开*时,如何解决歧义问题?

    因此 在学习 Haskell 时 我很快就遇到了可怕的单态限制 在 ghci 中 Prelude gt let f print show Prelude gt f 5
  • 在 Haskell 中等待然后检测按键的简单方法是什么?

    我对 Haskell 还很陌生 所以我正在寻找一种简单的方法来检测按键 而不是使用getLine 如果有人知道任何库 或者知道一些这样做的技巧 那就太好了 如果有更好的地方可以问这个问题 请直接告诉我 我将不胜感激 如果您不想阻止 可以使用
  • Haskell:处理死锁的自引用列表

    GHC 允许永久阻止以下内容是否有任何有用的理由 list 1 tail list 看起来列表迭代器 生成器有点复杂 我们应该能够做一些更有用的事情 Return error Infinitely blocking list Return
  • 我们不应该使用单子绑定来使用循环写下 mfix 的情况

    我一直在尝试写mfix向下使用Control Arrow loop https hackage haskell org package base 4 14 0 0 docs src Control Arrow html loop 我想出了不
  • 不同 hs 文件中的函数分离时堆栈空间溢出

    我有一个巨大的 haskell 文件 它编译和运行没有任何问题 我想将一些函数和类型定义放在通用 hs 文件中的单独模块中 然后将其导入我的主模块中 虽然主程序编译时没有任何错误 它还编译导入的模块 但当我尝试运行它时 出现堆栈空间溢出 I
  • 计算两点之间的距离(Haskell)

    给定两个元组的输入 我希望能够使用以下公式计算两点之间的距离 距离 sqrt x1 x2 2 y1 y2 2 所以我希望函数调用和输出如下所示 gt distance 5 10 3 5 5 385 当我尝试运行下面的代码时 它告诉我输入 w
  • 如何找到仅是 2、3 和 5 的幂的倍数的所有数字的列表? [复制]

    这个问题在这里已经有答案了 I am trying to generate a list of all multiples which can be represented by the form where a b and c are w
  • GHC 是否使用存在类型的动态调度?

    下面的代码是否使用了 C 或 Java 中所理解的动态调度 据我了解 在最后一行 编译器不可能在编译时知道要调用哪个 实现 但代码会编译并产生正确的结果 有人可以解释一下 这背后有什么样的实现 例如 vptr 吗 LANGUAGE Exis
  • Haskell 中的相互递归求值器

    Update 我已经添加一个答案 https stackoverflow com questions 3524485 mutually recursive evaluator in haskell 4504200 4504200这描述了我的
  • 存在函数依赖关系时类型推断如何工作

    考虑下面的代码 LANGUAGE MultiParamTypeClasses FlexibleInstances FunctionalDependencies UndecidableInstances FlexibleContexts cl
  • 管道中缺少 ResourceT 实例

    我在尝试使用时遇到奇怪的错误ResourceT http hackage haskell org package conduit 1 0 9 1 docs Data Conduit html t 3aResourceT来自管道 1 0 9
  • 如何处理在组合下发生变化的类型?

    我最近读了一篇非常有趣的论文单调性类型 https infoscience epfl ch record 231867 files monotonicity types pdf其中描述了一种新的 HM 语言 该语言可以跟踪操作之间的单调性
  • Haskell 和 Idris 之间的区别:类型宇宙中运行时/编译时的反映

    因此 在 Idris 中 编写以下内容是完全有效的 item b Bool gt if b then Nat else List Nat item True 42 item False 1 2 3 cf https www youtube

随机推荐

  • random.randint 在具有相同种子的 Python 2.x 和 Python 3.x 中显示不同的输出

    我正在将应用程序从 python 2 移植到 python 3 并遇到以下问题 random randint根据使用的Python版本返回不同的结果 所以 import random random seed 1 result random
  • Java Spring @Scheduled 任务执行两次

    我这里有一个简单的测试方法 设置为每 5 秒运行一次 并且确实如此 但是查看 System out 您可以看到它似乎在做一些奇怪的事情 Scheduled cron 5 public void testScheduledMethod Sys
  • 从 EJB3 迁移到 Spring、Hibernate

    我们有一个基于 EJB3 Oracle 10 和 JBoss 4 的桌面应用程序 这是大约三年前创建的 JPA 实体用于 ORM 业务逻辑在无状态会话 bean 中实现 客户端是使用Swing API 开发的 现在需要在下一个版本的应用程序
  • Android 片段屏幕重叠

    我有一个使用片段的应用程序 在我的用户的一台设备 HTC One 上 碎片相互重叠 他的屏幕最终看起来一团糟 我尝试在自己的硬件上重现它 尽管它不是 HTC One 我也尝试过使用 android 版本 4 1 2 这是他拥有的版本 并且运
  • Flutter:如何使整行可点击

    如何使整行在颤振中可点击 我将以下代码包装在 GestureDetector 中 行中的各个项目是可单击的 但小部件周围的空白区域不可单击 if auth isLoggedIn GestureDetector onTap auth sign
  • 如何生成sse4.2 popcnt机器指令

    使用c程序 int main int argc char argv return builtin popcountll 0xf0f0f0f0f0f0f0f0 和编译器行 gcc 4 4 Intel Xeon L3426 gcc msse4
  • org-mode 无法编辑 C 源代码

    当我使用 emacs 的 org mode 编辑 C 程序时 即编辑以下代码段 begin src c define MAX 100 end src 当我调用函数 org edit src code 在新缓冲区中编辑 C 代码后 出现错误
  • 如何用Java“正确”检测显示器的DPI?

    我有以下绘制规则的应用程序 public class Rule extends JComponent public static final long serialVersionUID 26362862L public static fin
  • SQL 对值求和

    我是 SQL 新手 我不知道如何做到这一点 我想对类似的对 vin action 求和一个名为 total spending 的coulmn 并选择第一个dealer name和参考月份年份 因此它不会创建重复项 并具有如下示例的输出 输入
  • 使用shell脚本删除文件夹内容

    我在尝试清空脚本中的文件夹时遇到问题 这在我的命令行中工作 rm r Folder1 Folder2 但如果在我的脚本中我这样做 DIR Folder1 Folder2 rm r DIR 它说 rm Folder1 Folder2 没有这样
  • Makefile:多重定义和未定义的引用错误

    我目前正在学习如何在没有 IDE 的情况下进行编码 因此我正在学习如何编写 makefile 这是我当前的测试项目 CoDstructor Makefile bin CoDstructor exe src cod main cpp type
  • Windows Azure 不生成 aspx 文件

    我设置了我的第一个 Azure Cloude 服务和 Web 角色 当我构建然后发布应用程序时 我只能看到包含所有 dll 的 bin 目录 我没有任何文件夹或 aspx 文件 ProjectName CloudService bin De
  • ASP.Net Core 2.0 中 [AllowHtml] 的替代品是什么[重复]

    这个问题在这里已经有答案了 我想将 CKEditor 集成到我的 MVC Core 2 0 应用程序中 在之前的版本中 我通过向字符串属性添加 AllowHTML 数据注释来使用它 但在 ASP Net Core 中我找不到将 HTML 插
  • 想要列表中不重复的元素

    从下面的列表中 我只需要 哇 和 退出 List
  • Rails 中的一对一或零关联

    Model I class TimeLog lt ActiveRecord Base has one custom time fields dependent gt destroy end Model II class CustomTime
  • 在代号一中使用 LocationManager 的正确方法

    我正在使用 LocationManager 来跟踪用户的位置并在 GoogleMaps 上显示相同的位置 我正在使用以下方法 但对此有一些疑问 为了第一次获取用户的位置 我使用 locationManager LocationManager
  • Microsoft VB.NET 命名约定

    VB NET 有标准命名约定吗 根据您的编程经验 想分享您对 VB NET 的命名约定吗 除了这种良好实践之外 还有任何指南吗 模式与实践 http www codeplex com Wiki View aspx ProjectName g
  • kubectl 端口转发和 NodePort 服务之间的区别

    kubectl port forwarding 将端口从本地主机转发到集群中的 pod 以获取对集群资源的访问权限 和 NodePort 服务类型之间有什么区别 您正在比较两个完全不同的事物 你应该compare https medium
  • 添加 google-play-services 后,您需要在此活动中使用 Theme.AppCompat 主题(或后代)

    在我目前正在开发的应用程序中 这是我的第一个 Android 应用程序 我使用 android maven plugin 和 maven android sdk deployer 应用程序一直运行良好 使用 ActionBarActivit
  • 类型类是必需的吗?

    我曾经问过一个问题哈斯克尔初学者 https groups google com forum topic haskell cafe C1zGMkYGTOY 是否使用 data newtype 还是类型类 在我的特殊情况下 事实证明不需要类型