在用户定义类型和现有类型之间定义已存在(例如在 Prelude 中)运算符的正确方法是什么?

2024-03-21

假设我有一个包装现有类型的自定义类型,

newtype T = T Int deriving Show

假设我希望能够加起来Ts,并且将它们相加应该会导致将包装值相加;我会通过以下方式做到这一点

instance Num T where
  (T t1) + (T t2) = T (t1 + t2)
  -- all other Num's methods = undefined

我认为到目前为止我们都很好。请告诉我到目前为止是否存在重大问题。

现在假设我想要能够乘以T by an Int结果应该是T其包装值是前者乘以 int;我会去做这样的事情:

instance Num T where
  (T t1) + (T t2) = T (t1 + t2)
  (T t) * k = T (t * k)
  -- all other Num's methods = undefined

这显然行不通,因为class Num宣称(*) :: a -> a -> a,因此要求两个操作数(和结果)都是相同的类型。

甚至定义(*)作为一个自由函数会带来类似的问题(即(*)已经存在于Prelude).

我该如何处理这个问题?

至于为什么会出现这个问题,我可以推测如下

  • 在我的程序中我想使用(Int,Int)对于笛卡尔平面中的 2D 向量,
  • 但我也用(Int,Int)对于另一件不相关的事情,
  • 因此我必须通过使用来消除两者之间的歧义newtype至少其中之一,或者,如果使用(Int,Int)由于其他几个原因,那么为什么不全部制作newtype包装(Int,Int)?
  • since newtype Vec2D = Vec2D (Int,Int)表示平原中的向量,能够做到这一点是有意义的Vec2D (2,3) * 4 == Vec2D (8,12).

非常相似的例子已经经常被问到,答案是这是not数字类型,因此不应有Num实例。它实际上是一个向量空间 http://hackage.haskell.org/package/vector-space类型,相应地你应该定义

{-# LANGUAGE TypeFamilies #-}

import Data.AdditiveGroup
import Data.VectorSpace

newtype T = T Int deriving Show

instance AdditiveGroup T where
  T t1 ^+^ T t2 = T $ t1 + t2
  zeroV = T 0
  negateV (T t) = T $ -t

instance VectorSpace T where
  type Scalar T = Int
  k *^ T t = T $ k * t

那么你的T -> Int -> T运算符是^* http://hackage.haskell.org/package/vector-space-0.16/docs/Data-VectorSpace.html#v:-94--42-,这就是简单的flip (*^).

这也导致了在重载具有不同含义的标准运算符时应该做的更一般的事情:只需将其设为separate定义。您甚至不需要给它一个不同的名称,这也可以使用来消除歧义qualified模块导入。

只是请不要不完整地实例化类,特别是Num。当有人使用这些类型的泛型函数时,这只会导致 php 式的混乱,它编译得很好,但当调用代码期望时,它会在运行时可怕地中断Num语义,但类型实际上未能提供该语义。

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

在用户定义类型和现有类型之间定义已存在(例如在 Prelude 中)运算符的正确方法是什么? 的相关文章

  • 如何在createQueryBuilder中使用通配符?

    在我的存储库类中 我使用 public function getItemsByTag tag qb this gt createQueryBuilder c gt select c gt where c tags LIKE bipolar
  • 在 OpenXML 中应用数字格式

    我正在尝试使用 OpenXML 从头开始 创建 Excel 电子表格 并且一切正常 将实际值转储到实际单元格中 但现在我正在尝试将数字格式应用于列 但遇到了问题 我有styles xml看起来像这样
  • 如何使盒子阴影显示在容器中的下一个元素上?

    请看这段代码 http codepen io Varin pen kkGgVd http codepen io Varin pen kkGgVd div class container div class outside2 div clas
  • 使用 Swift 解析框架

    有人尝试过将 Parse Framework 与 swift 一起使用吗 只要添加桥接文件 您就可以使用 swift 和 Objective C 代码 这是我的查询 从 Parse 返回的 对象 数组正确地包含了我的所有数据 但该方法在将
  • 为什么 .each 在我的 Rails 视图中完成后会重复数组? [复制]

    这个问题在这里已经有答案了 在我的 Rails 视图页面中 我有以下循环 它应该循环遍历我的 tag list 数组并打印每个标签 由于某种原因 它在打印每个单独的标签后会重复该数组 例如 这个数组有两个元素 ruby python 每个方
  • 使用 CDI+JSF 使会话失效不起作用

    我正在尝试在我的应用程序中实现注销 所以我这样做了 public String logout try FacesContext facesContext FacesContext getCurrentInstance ExternalCon
  • Google 地图 api 中的 infoWindow 数组

    我寻找错误 但找不到它 由于某种原因 任何谷歌地图信息窗口总是显示相同的信息 这是一个咖啡脚本代码 infowindow new google maps InfoWindow for company in companiesData mar
  • 使用 OpenLayers 动态添加自定义标记到地图

    我想让用户在地图上添加自定义标记以及每个标记的描述 任何提示 任何教程的链接都会非常有用 您可以注册一个函数来在地图上 点击 事件 当用户单击它时 会自动添加该标记 尝试这样的事情 map is your map created using
  • 使用 PowerShell 检查 AD 中是否存在组

    我想为该组创建代码来检查该组是否存在 但是 我无法开始工作 因为它成功地将用户和组的部分成员仅添加到一个组中 而不是其他组 因为我设法在活动目录中创建一个组并从 csv 中读取 这是我的代码和结果 似乎在成功添加用户并添加组成员后我总是收到
  • 新的 .NET 6 控制台模板中的 C# 函数重载不起作用

    我在尝试重载该函数时遇到错误Print object in the 新的 NET 6 C 控制台应用程序模板 https learn microsoft com en us dotnet core tutorials top level t
  • python中匹配3个或更多相同的字符

    我正在尝试使用正则表达式在字符串中查找三个或更多相同的字符 例如 你好 不匹配 噢 会的 我尝试过做类似的事情 re compile 1 3 a zA Z re compile w 1 5 但似乎都不起作用 w 1 2 是您正在寻找的正则表
  • 如何在运行时更改 UIMenu 内 UIAction 的状态?

    如何更改 UIAction 的状态 目标是切换 UIMenu 内 UIAction 旁边的状态复选标记 更改 UIAction 的state通过存储在视图控制器中的引用似乎根本不会改变状态 我错过了什么吗 View Controller i
  • PDO 返回不正确但重复的数据。密钥不在数据库中。

    我刚开始使用 pdo 语句 所以可能是一些简单的东西 我还没有在 php net 上读过 查询数据库时我收到重复的结果 Result 0 gt Array umeta id gt 31 0 gt 31 user id gt 2 1 gt 2
  • 在Java的System.out中以表格格式输出

    我正在从数据库获取结果 并希望将数据作为 Java 标准输出中的表输出 我尝试过使用 t 但我想要的第一列的长度变化很大 有没有办法将其显示在类似输出的漂亮表格中 Use System out format http java sun co
  • Shap - 颜色条不显示在摘要图中

    显示summary plot时 不显示颜色条 shap summary plot shap values X train 我尝试过改变plot size 当绘图较高时 会出现颜色条 但它非常小 看起来不应该 shap summary plo
  • 将元素添加到 D3 圆包节点

    我正在尝试制作一个可缩放的圆形包装图 我希望每个子圆圈包含一个较小的图表 该图表始终具有相同的结构 即 4 列 只有条形的高度会改变 我尝试添加一个简单的rect到目前为止我的图表 但矩形没有添加到圆圈中并且是静态的 JS var marg
  • FindAsync 很慢,但是延迟加载很快

    在我的代码中 我曾经使用加载相关实体await FindAsync 希望我能更好地遵守 C 异步指南 var activeTemplate await exec DbContext FormTemplates FindAsync exec
  • Javascript:修改原型不会影响现有实例[重复]

    这个问题在这里已经有答案了 我创建了原型的 2 个实例 更改了原型中的函数 更改反映在两个实例中 很棒 但是 当我通过删除该函数来修改原型时 该函数对于现有实例仍然存在 function A this name cool A prototy
  • 同时有两个操作栏(底部和向上)?

    我需要制作两个操作栏 顺便说一下我正在使用actionBarSherlock 所以我真正需要的是在正常操作栏上放置一个 欢迎屏幕 开关 并添加两个正常的 ActionBar 操作选项 与我需要的类似的是 Gmail 和地图 如下所示 htt
  • 如何使用反应本机在数字键盘上添加“完成”按钮

    我在react native中使用数字键盘 我想在单击完成按钮时隐藏键盘 因为我想在键盘上方添加完成按钮 是否有可能像IOS应用程序一样隐藏键盘 任何帮助非常感激 我不确定这是否正是您想要的 但您可以使用 prop returnKeyTyp

随机推荐

  • AWS:为实例指定安全组时,其 ENI 是否在幕后指定了安全组?

    这里我有一个AWS实例 它指定了两个安全组default and my first group 现在我想让这个实例 ssh 可用 以下两种方式都有效 使用新的安全组指定该实例ssh available 或者 找到该实例的弹性网络接口 ENI
  • 严重:为 servlet 分配异常 java.lang.ClassNotFoundException: 异常 [重复]

    这个问题在这里已经有答案了 当我使用以下内容时web xml 我的项目运行良好 我可以看到 Hello World 通过index jsp 页面显示 我在用网豆 7 4 and 阿帕奇汤姆猫 6 0 41
  • 如何删除 JavaScript 中的查询字符串参数?

    除了使用正则表达式之外 是否有更好的方法可以从标准 JavaScript 中的 URL 字符串中的查询字符串中删除参数 这是我到目前为止所想出的 似乎在我的测试中有效 但我不喜欢重新发明查询字符串解析 function RemovePara
  • 在android中使用Intent选择PDF文件

    嘿 我是 android 新手 我有一个选择要求pdf文件使用Intent 我正在使用此代码来设置 MIME 类型 Intent intent new Intent Intent ACTION GET CONTENT intent setT
  • Android Studio 无法解析导入项目中的 R?

    我正在尝试新的 Android Studio 我使用 build gradle 选项从 eclipse 导出了一个项目 然后我将其导入到 Android Studio 中 gen下的R java文件上面有一个小红圈的j 在我的源文件中 只要
  • 当选中某个项目时,UpdatePanel 内的复选框列表会触发完整回发

    所以我有这个复选框列表 我想为其内部的元素实现全选功能 我将其放置在 UpdatePanel 中 但每次单击某个项目时 整个页面都会重新加载 这是我的代码
  • 如何使用 VIM 搜索项目的所有文件?

    有几件事我还不明白 VIM 方式 其中之一是在项目中进行搜索 如下所示 在 Atom 中使用 VIM 我目前使用 CtrlP 作为文件名 但是内容呢 如何使用字符串进行搜索 然后使用 VIM 和 或 VIM 插件查看所有出现的事件的列表 我
  • launchctl 无法运行二进制文件并以代码 78 退出

    我一直在构建一个 golangapp https gist github com krlc 8b9a79b33b857d1a66221ffc802d3c0d带有系统托盘 GUI 我想了launchctl每当我登录时运行我的程序 程序编译并运
  • 使用 Docker Compose 的交互式 shell

    有没有办法仅使用 Docker Compose 在容器中启动交互式 shell 我在 docker compose yml 中尝试过类似的操作 myapp image alpine latest entrypoint bin sh 当我使用
  • SublimeLinter:PHP linting 不起作用

    PHP linting 不适用于SublimeLinter https github com SublimeLinter SublimeLinter虽然它说PHP loaded在控制台中 我正在 Windows 上工作 此外 如果我打开命令
  • 哪里可以找到Hibernate的DTD?

    hibernate jar 中的 DTD 是了解可以包含哪些属性以及该标记的预期名称的好方法 打开 DTD 文件是获取所有元素和属性概览 查看默认值以及一些注释的最简单方法 这将帮助程序员从头开始编写 hibernate cfg xml 文
  • VS2022:如何使 ASP.NET Core 5 应用程序显示其控制台窗口

    在 VS2019 中 当我启动 ASP NET Core 5 应用程序时 它只公开一个 API 如果重要的话 会弹出该应用程序的控制台窗口 曾经有一些设置来决定是将其作为控制台 独立应用程序运行还是将其托管在 IIS Express 中 我
  • Glassfish 4不加载js文件

    我最近搬家了 从 glassfish 3 1 jsf 2 0 primefaces 3 5 java 6 到 glassfish 4 jsf 2 2 primefaces 5 java 8 Javascript 文件 通常是 Primefa
  • 是否可以在没有开发者 ID 的情况下测试推送通知?

    在 xcode 7 beta 版本之后 我可以在没有开发者 ID 的情况下在真实设备上安装应用程序 但是 我们可以做同样的事情吗 push notification 还是必须申请开发者ID 如果有方法请参考链接 为了使用 Apple 推送通
  • Sequelize 查找软删除的行

    我试图从数据库中获取一些已软删除的行和一些未软删除的行 但它对我不起作用 Model findAll where cond xxx include Model2 paranoid false then function rows do so
  • 使用 Apache tika 删除 PDFont 缓存

    我试图仅从许多不同的代码 rtf doc pdf 中提取文本 我很自然地转向 Apache Tika 因为它可以自动检测文档并相应地提取文本 我只对文本感兴趣 对格式等不感兴趣 我的应用程序最终出现了严重的内存泄漏 经过调查 这是来自 PD
  • Jquery 可拖放和可排序组合

    我被要求创建一个正方形网格 其中每个正方形可能包含也可能不包含链接 并且这些链接应该能够在网格上移动 我认为可拖动 可放置将是一种可行的方法 并且它工作得很好 但是 现在我们希望能够在一个可拖动对象放在另一个对象之上时能够交换可拖动对象 所
  • t-sql udf,获取参数的数据类型

    是否可以为我的 udf 获取数字参数 并根据其类型执行操作 例如 如果 p1的类型是decimal 10 3 否则如果 p1的类型是decimal 15 3 否则如果 p1 的类型是整数 尝试 sql variant property 函数
  • 字符串的最小字典值

    当使用运算符 smallest string 更具体地说 什么是比任何其他字符串更小的 使用 空字符串是所有字符串中 最小 的 也就是说 它比任何非空字符串都小 21 4 8 4 字符串 op template
  • 在用户定义类型和现有类型之间定义已存在(例如在 Prelude 中)运算符的正确方法是什么?

    假设我有一个包装现有类型的自定义类型 newtype T T Int deriving Show 假设我希望能够加起来Ts 并且将它们相加应该会导致将包装值相加 我会通过以下方式做到这一点 instance Num T where T t1