代数类型数据构造函数的“模式匹配”

2024-02-15

让我们考虑一个具有许多构造函数的数据类型:

data T = Alpha Int | Beta Int | Gamma Int Int | Delta Int

我想编写一个函数来检查是否使用相同的构造函数生成两个值:

sameK (Alpha _) (Alpha _) = True
sameK (Beta _) (Beta _) = True
sameK (Gamma _ _) (Gamma _ _) = True
sameK _ _ = False

维护sameK没什么乐趣,不能轻易检查其正确性。例如,当新的构造函数添加到T,很容易忘记更新sameK。我省略了一行来举个例子:

-- it’s easy to forget:
-- sameK (Delta _) (Delta _) = True

问题是如何避免样板代码sameK?或者如何确保它检查所有T构造函数?


我发现的解决方法是为每个构造函数使用单独的数据类型,派生Data.Typeable,并声明一个通用类型类,但我不喜欢这个解决方案,因为它的可读性要差得多,否则只有一个简单的代数类型适合我:

{-# LANGUAGE DeriveDataTypeable #-}

import Data.Typeable

class Tlike t where
  value :: t -> t
  value = id

data Alpha = Alpha Int deriving Typeable
data Beta = Beta Int deriving Typeable
data Gamma = Gamma Int Int deriving Typeable
data Delta = Delta Int deriving Typeable

instance Tlike Alpha
instance Tlike Beta
instance Tlike Gamma
instance Tlike Delta

sameK :: (Tlike t, Typeable t, Tlike t', Typeable t') => t -> t' -> Bool
sameK a b = typeOf a == typeOf b

另一种可能的方式:

sameK x y = f x == f y
  where f (Alpha _)   = 0
        f (Beta _)    = 1
        f (Gamma _ _) = 2
        -- runtime error when Delta value encountered

运行时错误并不理想,但比默默给出错误答案要好。

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

代数类型数据构造函数的“模式匹配” 的相关文章

  • Haskell 中美元符号 ($) 和 id 函数之间有关系吗?

    这几天我正在读一篇评论莫纳德挑战 http mightybyte github io monad challenges 我强烈推荐给像我这样的 Haskell 初学者 我最终得到了这个线程 https news ycombinator co
  • Haskell 中函数和函子有什么区别?只有定义吗?

    在 Haskell 中 当编写函数时 这意味着我们将某个东西 输入 映射到另一个东西 输出 我尝试 LYAH 来理解 Functor 的定义 看起来和普通 Functor 一样 函数被称为函子有什么限制吗 Functor 是否允许有 I O
  • 最后一项具有不同类型的元组(首先从剩余元素开始)

    我有一个类型Foo那是一个Array可以包含任意数量的Bar元素 带有可选的最后一个Qux元素 以下是一些有效数据的示例 bar qux bar qux bar bar bar bar bar bar bar bar qux 无效数据示例
  • 生成所有可能的树

    给定以下数据类型定义 data FormTree Empty Node FormTree FormTree deriving Show 我想编写一个函数 它生成一个无限列表 其中包含按长度排序的所有可能的树 例如节点数量 下面的代码几乎满足
  • 整数转浮点数

    这段代码的工作原理 posToXY Float gt Float gt Integer posToXY a b do let y a b round y 但这不起作用 posToXY Integer gt Integer gt Intege
  • ErrorT 已弃用,但 exceptT 不适合

    我有一个一元计算 在某些时候 由于单子模式匹配 它开始需要 MonadFail 约束 我的简单解决方法是使用以下命令运行它 fmap either error id runErrorT 然而哎呀 Deprecated Use Control
  • 如何从 haskell 中的 IOError 获取 errno?

    我在 haskell 平台上 GHC 6 12 1 作为 apt get 安装在 Debian Squeeze 上 鉴于我需要在与最初引发它的线程不同的线程上使用它 如何从 IOError 中获取底层 errno 我需要这个的原因是因为我正
  • DataFrame 中的字符串,但 dtype 是对象

    为什么 Pandas 告诉我我有对象 尽管所选列中的每个项目都是一个字符串 即使在显式转换之后也是如此 这是我的数据框
  • 当两个模式共享“when”子句时,模式匹配不完整

    A 共同的惊喜 https stackoverflow com q 18691622 2314532对于 F 初学者来说 以下事实是不完全匹配 let x y 5 10 match something with when x lt y gt
  • 这个记忆的斐波那契函数是如何工作的?

    在我正在做的函数式编程课程的当前练习作业中 我们必须制作给定函数的记忆版本 为了解释记忆化 给出以下示例 fiblist fibm x x lt 0 fibm 0 0 fibm 1 1 fibm n fiblist n 1 fiblist
  • Haskell 类型系统的细微差别

    我一直在深入了解 haskell 类型系统的本质 并试图了解类型类的要点 我已经学到了很多东西 但我在下面的代码片段上遇到了困难 使用这些类和实例定义 class Show a gt C a where f Int gt a instanc
  • 为什么 Haskell 的默认字符串实现是一个字符链接列表?

    Haskell 默认值的事实String众所周知 实现在速度和内存方面都效率不高 据我所知 lists一般来说 在 Haskell 中实现为单链表 并且适用于大多数小型 简单数据类型 例如Int 这似乎不是一个好主意 但是对于String这
  • 将数据类型设置为 Kind * -> * 这不是函子

    布伦特 约尔吉类型分类百科全书 https www haskell org haskellwiki Typeclassopedia给出以下练习 举一个类型的例子 gt 不能将其制成 的实例Functor 不使用undefined 请告诉我什
  • 什么是欣德利米尔纳?

    我遇到过这个词欣德利 米尔纳 我不确定是否理解它的意思 我已阅读以下帖子 史蒂夫 叶格 动态语言的反击 http steve yegge blogspot com 2008 05 dynamic languages strike back
  • System.Web.HttpException 无法加载类型“[命名空间].???”

    这开始于无法加载类型 全局 错误 在我尝试了一些方法后 没有找到删除 Global asax 文件的位置 现在错误是无法加载类型 namespace 在哪里 是我尝试加载的每个页面的类名 该网站 在 VS2008 本地开发计算机中执行时 工
  • 持久 selectList 导致错误“无法将类型‘BaseBackend backend0’与‘SqlBackend’匹配”

    我遇到以下编译错误 Couldn t match type BaseBackend backend0 with SqlBackend arising from a use of runSqlite The type variable bac
  • 搜索重写规则

    有什么办法可以浏览或搜索重写规则吗 当我使用像这样的标志时 ddump rule firings or ddump rule rewrites我只是得到了触发的规则的名称以及它引起的重写 但没有得到实际的规则本身 理想情况下 我想通过 GH
  • Scala:如何将可变参数指定为类型?

    代替 def foo configuration String String 我希望能够写 type Configuration String String def foo configuration Configuration 主要用例是
  • 规范化且不可变的数据模型

    Haskell如何解决 规范化不可变数据结构 问题 例如 让我们考虑一个表示前女友 男友的数据结构 data Man Man name String exes Woman data Woman Woman name String exes
  • 如何在 Haskell 中安装库?

    我尝试使用控制 Monad Extra andM https hackage haskell org package extra 1 7 10 docs Control Monad Extra html import Control Mon

随机推荐

  • t-sql子串

    我基本上有一列需要进行子串化 该列的格式如下所示 Column A Root FOLDERPATH somesubfolderpath somedocument doc 第一个字符串 Root 将始终具有相同的长度和相同的字符 Root 之
  • ORB 计算错误:它删除了小图像的所有关键点

    我有一个 50x50 的小图像 我找到 ORB 关键点 请注意 我必须将 patchSize 的默认参数从 31 更改为 14 才能检测到一些关键点 OrbFeatureDetector det 500 1 2f 8 14 0 2 0 14
  • 会话在 IHttpModule 中不可用

    在我的程序中 我尝试在 IHttpModule 中使用会话变量 这是我的代码 这在 VS 2010 开发服务器中运行良好 但是当我尝试在 IIS7 中调试时 它显示异常System Web HttpException Session sta
  • 打开工作簿时关闭 Excel 后台错误检查

    我有一个 Excel 工作簿 里面有很多绿色的 错误检查 三角形 有什么方法可以使用 Excel VBA 在打开工作簿时关闭此功能 我认为这就是您正在寻找的 Application ErrorCheckingOptions Backgrou
  • Mongodb 聚合框架解释

    MongoDB 中的聚合框架有解释函数吗 我在文档中看不到它 如果没有 是否有其他方法可以检查查询在聚合框架内的执行情况 我知道你只是做 db collection find explain 但是使用聚合框架时出现错误 db collect
  • 使用 OraOLEDB 提供商部署应用程序

    我开发了一个使用Delphi 7 ADO和ORACLE的应用程序 我使用的提供程序是OraOLEDB 我需要使用这个提供程序 因为BLOB字段支持 现在我想与提供商一起分发此应用程序 我在网上搜索下载甲骨文提供商 http www orac
  • 使用 LLVM pass 添加内在函数

    我使用 LLVM 通道向输入代码添加了一个内在函数 我能够看到内部调用 但我无法弄清楚如何将代码编译到我的目标架构 x86 64 我正在运行以下命令 clang llvm config ldflags libs all ff s o foo
  • GNU 编译器优化

    我对编译器了解不多 但知道它们足够复杂和智能 可以优化您的代码 假设我的代码如下所示 string foo bar for int i 0 i lt foo length i some code that does not modify t
  • 从 Rails 应用程序(Word、PDF、Excel 等)搜索附件

    我在 Stack Overflow 上发表的第一篇文章 请温柔一点 我即将为客户启动一个新的 Ruby on Rails 3 1 项目 他们的要求之一是有一个搜索引擎 该引擎将索引大约 2 000 个文档 这些文档是 PDF Word Ex
  • 让 TortoiseSVN 将文件的修改时间设置为最新修订的时间戳

    我似乎记得能够得到乌龟SVN http en wikipedia org wiki TortoiseSVN在执行更新时将文件的上次修改时间戳设置为修订版的时间戳 因此 如果有人五天前提交了一个文件并且我更新了它 则修改后的时间戳将是五天前
  • 如何在没有密码的情况下使用paramiko连接到远程服务器?

    我正在用 Python 编写一个脚本 需要连接到remote server使用 SSH 并移动file from remote server to host server 我需要在没有密码的情况下执行此操作 因为它需要适用于任何远程服务器和
  • Varnish:清除说它有效,但不会删除旧内容

    我正在 Digital Ocean Ubuntu VM 上运行一个独立的 varnish 实例 它基本上工作正常 该设置用于承担位于其他地方的旧 WordPress 服务器的负载 这很有效 但我很难清除内容 当谈论清除时 我的意思是使 UR
  • 使用 SWIG,如何将 C++ void func(Class& out) 包装为 C# Class func()?

    不幸的是 SWIG 的文档非常难以解析 而且在线示例似乎很少 所以我来到这里 假设 C 函数对类类型使用以下典型返回样式 void func Class out 使用 SWIG 这个函数应该像这样用 C 包装 Class func 根据我的
  • 是否有使用 C# + ASP.NET 实现国际化的基本教程? [关闭]

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

    我该如何调试CMakeLists txt文件 至少做诸如列出变量之类的事情 而不仅仅是使用the message command https cmake org cmake help latest command message html
  • 如何修复 C++ 中的“对 Array::Array(unsigned long) 的未定义引用”? [复制]

    这个问题在这里已经有答案了 我有一个用于对 char 数组进行排序的类 其中一个构造函数采用参数 size t 长度 当我向它传递 int 类型的长度并尝试编译时 出现错误 driver cpp text 0x2c 对 Array Arra
  • 如何使用 CMake 添加额外的 plist 属性?

    我正在尝试添加该项目
  • React-Native 中的 Alt @decorators

    我正在使用Alt http alt js org 带有 React Native 的库 Flux 实现 我真的很喜欢 alt utils decorators 和 alt utils connectToStores 但我无法使用这些 dec
  • Chainlink节点:交易待处理时该怎么办?

    我有一个 chainlink 节点 并且有些交易似乎被卡住了 如何修复待处理的传出确认 大多数情况下 您没有使用 Gas 为您的 chainlink 节点账户提供资金 转到您的配置并获取ACCOUNT ADDRESS并将 ETH 发送到该地
  • 代数类型数据构造函数的“模式匹配”

    让我们考虑一个具有许多构造函数的数据类型 data T Alpha Int Beta Int Gamma Int Int Delta Int 我想编写一个函数来检查是否使用相同的构造函数生成两个值 sameK Alpha Alpha Tru