Haskell 中的异构多态性(正确方法)

2024-05-05

让一个模块来抽象Area操作(错误的定义)

class Area someShapeType where
  area :: someShapeType -> Float

-- module utilities
sumAreas :: Area someShapeType => [someShapeType]
sumAreas = sum . map area

Let a 后验的显式形状类型模块(良好或可接受的定义)

data Point = Point Float Float

data Circle = Circle Point Float
instance Surface Circle where
  surface (Circle _ r) = 2 * pi * r

data Rectangle = Rectangle Point Point
instance Surface Rectangle where
  surface (Rectangle (Point x1 y1) (Point x2 y2)) = abs $ (x2 - x1) * (y2 - y1)

放一些数据

c1 = Circle (Point 0 0) 1
r1 = Rectangle (Point 0 0) (Point 1 1)

然后,尝试使用

totalArea = sumAreas [c1, r1]

the [c1, r1]类型必须扩展为[Circle] or [Rectangle]! (并且无效)

我可以使用forall and额外的data像这样输入

data Shape = forall a . Surface a => Shape a

sumSurfaces :: [Shape] -> Float
sumSurfaces = sum . map (\(Shape x) -> surface x)

然后,接下来的代码运行成功

sumSurfaces [Shape c1, Shape r1]

但我认为,使用data Shape and Shape构造函数(在[Shape c1, ...]和 lambda 参数)是丑陋的(我的第一个[也是坏]方法很漂亮)。

正确的做法是什么“Haskell 中的异构多态性”?

非常感谢您的宝贵时间!


你的第一个(也是糟糕的)方法并不漂亮,它是Lispy。这在静态类型语言中是不可能的;即使你在例如中做了这样的事情Java 实际上是通过使用基类指针引入了一个单独的量化步骤,这类似于data Shape = forall a. Surface a.

关于存在量化是否好还存在争议,我认为大多数 Haskellers 不太喜欢它。在这里使用它肯定不是正确的:sum [ area c1, area c2 ]更容易并且效果也更好。但确实存在一些看起来不同的更复杂的问题;当你“需要”异构多态性时,存在主义就是正确的选择。

只要记住你总是可以解决这个问题:由于 Haskell 很懒,你可以应用所有可能的操作(在这个例子中它只是area)“先发制人”,将所有结果存储在某个记录中,并输出这些记录的列表而不是多态对象的列表。这样您就可以保留所有信息。

或者,更惯用的是,根本不生成此类对象的列表。你想对这些对象做一些事情,那么为什么不直接传递这些对象呢?actions进入你产生不同的函数Shapes,并将它们应用到位!这种逆转将存在量化转变为普遍量化,后者被更广泛地接受。

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

Haskell 中的异构多态性(正确方法) 的相关文章

随机推荐

  • Rails - 将模块包含到控制器中,以在视图中使用

    我对 Rails 很陌生 我尝试设置一个要在视图中使用的模块文件 所以我相信正确的行为是将模块定义为控制器中的助手 瞧 它应该可以工作 然而 对我来说情况并非如此 这是结构 lib functions form manager rb 表单管
  • 如何使用哈希表在最小堆上实现 O(1) 删除

    在某处阅读以下声明 可以使用附加的哈希表来快速删除 最小堆 问题 gt 如何组合priority queue and unordered map这样我就可以实现上面的想法了 include
  • 在 Mathematica 中使用 f@expr 和 expr // f 得到不同的结果

    我正在玩Prefix and Postfix运算符 and 分别 我遇到了以下问题 给定以下代码 它们以完全相同的方式进行评估 Hold MatrixPlot Sort data FullForm Hold MatrixPlot Sort
  • Java心跳设计

    我需要在我的 Java 项目上实现一个心跳系统 3 5 个客户端和 1 个服务器 但我有一些问题 1 客户端需要有 2 个套接字吗 1 用于心跳 1 用于接收我的软件的正常消息 2 我看到在特定情况下 当客户端滞后时 客户端不会收到消息 如
  • angular.js 的智能感知在 javascript 文件中不起作用

    我使用的是 Visual Studio 2013 它支持 Angular js 的 Intellisense 当我在 HTML5 文件的脚本标记内创建 Angular js 模块时 Intellisense 确实可以工作 但是 当我尝试在
  • emacs 的最佳 java 工具 [关闭]

    就目前情况而言 这个问题不太适合我们的问答形式 我们希望答案得到事实 参考资料或专业知识的支持 但这个问题可能会引发辩论 争论 民意调查或扩展讨论 如果您觉得这个问题可以改进并可能重新开放 访问帮助中心 help reopen questi
  • 无法向 kafka 主题发送消息

    我正在使用 Kafka Play 以及 Scala 这是我的代码 我想在其中发送消息到kafka服务器 主题名称是 测试主题 尽管我没有在主题中看到我发送的消息 但我没有收到任何错误 这里有什么问题吗 import kafka produc
  • Spark - java.lang.OutOfMemoryError:请求的数组大小超出 VM 限制

    我正在尝试对 Cloudera 的 Spark 2 1 0 中的数据帧进行 groupBy 操作 该集群位于总 RAM 约为 512GB 的 7 节点集群上 我的代码如下 ndf ndf repartition 20000 by user
  • Redis SYNC 套接字上的错误情况:连接被拒绝

    在我的 django 应用程序中使用 celery 和 redis 一切都工作正常 直到我遇到了问题 redis 文件的位置已更改 redis 无法访问它们 经过查找 原来这是由于网络随机攻击造成的 需要添加confg 我添加文件后 一段时
  • pyqt5调用url时处于无响应状态

    我刚刚在 pyqt 中实现了登录 但在调用 url 和获取响应之间 qt 窗口显示无响应状态 谁能建议我如何避免不响应状态 code class Login QDialog def init self height width parent
  • Selenium Webdriver sessionId 或检查所有浏览器窗口是否已关闭

    有没有办法查看所有浏览器窗口是否都已关闭 我发现如果您在 WebDriver 上调用 driver quit 或 driver close 则 sessionId 变为 null 有办法检查吗 我不想调用已关闭或退出的驱动程序 因为它会引发
  • JavaScript 闭包与匿名函数

    我和我的一个朋友目前正在讨论 JS 中什么是闭包 什么不是 我们只是想确保我们真正正确地理解它 我们以这个例子为例 我们有一个计数循环 想要在控制台上延迟打印计数器变量 因此我们使用setTimeout and closures捕获计数器变
  • 主键删除需要多长时间?

    画一个简单的表结构 Table1 Table2 ID lt ID Name gt Table1ID Name Table1有几百万行 例如 350 万行 我通过主键发出删除 DELETE FROM Table1 WHERE ID 100 中
  • 使用 PowerShell 从文本段落中提取 6 位数字字符串会产生空白数据

    尝试使用 PowerShell 从一段文本中提取 6 位数字字符串 但它仅在一种情况下有效 6 位数字字符串位于 Windows 剪贴板中的一段文本内 在我的代码中 我期望变量 Matches 0 是我要查找的 6 位数字 但结果始终为空
  • 在真实设备上通过命令行实现 UIAutomation

    我知道从Xcode 4 2可以运行UIAutomation通过命令行编写脚本 我已经尝试过这个并且在模拟器中对我来说工作得非常好 我想知道如何在实际设备中运行此命令 我搜索并获取了在设备上运行的命令 instruments w
  • Nginx - 自定义 404 页面

    Nginx PHP 在 fastCGI 上 对我来说非常有用 当我输入不存在的 PHP 文件的路径时 我不会得到默认的 404 错误页面 任何无效的 html 文件都会出现该错误页面 而只会得到 未指定输入文件 如何自定义此 404 错误页
  • 为什么要分离接口和实现?

    在生产代码中 我经常看到定义如下的类 public interface SomeComponent Some methods public class SomeComponentImpl implements SomeComponent S
  • Spark 上的 Hive 2.1.1 - 我应该使用哪个版本的 Spark

    我在跑蜂巢2 1 1 Ubuntu 16 04 上的 hadoop 2 7 3 根据Hive on Spark 入门 https cwiki apache org confluence display Hive Hive on Spark
  • 如何在命令行中更改现有变更列表的描述?

    命令 p4change 会提示编辑器并需要一个表单 但我想在命令行中执行此操作 我怎样才能实现这个目标 使用以下命令 p4 更改 u CL number 欲了解详情 请访问这一页 http www perforce com perforce
  • Haskell 中的异构多态性(正确方法)

    让一个模块来抽象Area操作 错误的定义 class Area someShapeType where area someShapeType gt Float module utilities sumAreas Area someShape