如何在类型级别用可选字段表示数据?

2024-01-21

我正在研究具有值(多态,可以是任何值)的控制流数据,而且它也could有一个验证器函数来检查该值是否仍然有效,并且could有一个“刷新值”的函数(返回具有新值的新数据)。

在 vanilla Haskell 中它可以看起来像这样:

data MyData a = MyData
  {value :: a
  ,validator :: Maybe (a -> Bool)
  ,refresher :: Maybe (MyData a -> MyData a)}

我真正想要的是这些类型:

data Refreshable = Refreshable | NotRefreshable
data Validatable = Validatable | NotValidatable
MyData (r :: Refreshable) (v :: Validatable)

我已经做到了,但只是与Refreshable。我想用Validatable也是,但我在构造函数方面遇到了问题。只为Refreshable我需要有两个构造函数,一个用于可刷新数据,另一个用于不可刷新数据。有了 validatable,我需要 4 个构造函数! (对于可刷新和可验证、对于不可刷新和可验证、对于可验证和不可刷新、以及对于不可刷新和不可验证)。想象一下我稍后是否需要另一个可选字段。更糟糕的是:除了那些正在变化的字段之外,几乎所有字段都是相同的,因此存在大量重复。


我还尝试用类型类/类型族来修改这种情况。
例如,MyData 'Refreshable 'NotValidatable就变成了Refreshable data => data我可以举个例子MyData或者只是将其删除以获取可以作为实例的更具体的数据。

这也是有问题的,因为它们不再是真正的字段;而是。即我无法在没有验证器的情况下获取数据并将其更改为相同的数据with验证器(不在类型级别)。


这可能是一个 XY 问题;我认为更干净的方法是使数据类型像Refreshable a and Validatable a并将它们写成MyData但我不知道该怎么做。我无法包装它们,因为顺序会改变一切。

有没有一种干净的方法来做到这一点?或者我应该坚持使用 4 个构造函数?或者也许 Haskell 还没有准备好应对此类事情? (没有双关语:P)。


这样的东西能满足您的要求吗?

import Control.Applicative (Const)
import Data.Functor.Identity

data MyData kv kr a = MyData
  {value :: a
  ,validator :: kv (a -> Bool)
  ,refresher :: kr (MyData a -> MyData a)}

-- examples
type FullData a      = Data Identity   Identity   a
type EmptyData a     = Data (Const ()) (Const ()) a
type ValidableData a = Data Identity   (Const ()) a

需要一些包装/展开(对于Identity).

可以定义助记符别名type Present = Identity and type Missing = Const (),带有一些扩展。


或者,

data MyData (v :: Opt) (r :: Opt) a = MyData
  {value :: a
  ,validator :: Validator v a
  ,refresher :: Refresher r a}

data Opt = Yes | No

type family Validator (o :: Opt) a where
    Validator Yes = (a -> Bool)
    Validator No  = ()
-- etc.

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

如何在类型级别用可选字段表示数据? 的相关文章

  • Haskell:IORef 的性能

    我一直在尝试在 Haskell 中编码一个需要使用大量可变引用的算法 但与纯粹的惰性代码相比 它 也许并不奇怪 非常慢 考虑一个非常简单的例子 module Main where import Data IORef import Contr
  • Haskell - lambda 表达式

    我试图了解什么是有用的以及如何在 Haskell 中实际使用 lambda 表达式 我不太明白使用 lambda 表达式相对于定义函数的约定方式有何优势 例如 我通常会执行以下操作 let add x y x y 我可以简单地打电话 add
  • 在 monad 转换器类型类中使用列表 monad?

    我的目标是创建一个在 ReaderT WriterT 堆栈或 RWS 堆栈中使用列表 monad 的函数 更一般地说 如何在 mtl 类型类 例如 MonadReader MonadWriter 中使用列表 monad 我为什么要尝试这样做
  • Data.Sequence 中的 inits 和 tails 如何工作?

    Louis Wasserman 编写了当前的实现inits and tails in Data Sequence 他表示它们非常高效 事实上 只要查看代码 我就可以看到 无论它们在做什么 它们都是以干净 自上而下的方式进行的 这往往会给惰性
  • 检查对以下内容的理解:“变量”与“变量” “价值”、“功能”与“抽象”

    这个问题是后续问题this one https stackoverflow com questions 25327705 is function a sort of variable 25329157 25329157在学习 Haskell
  • 管道:多个流消费者

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

    我知道 ST monad 有点像 IO 的弟弟 而 IO 又是添加了状态 monadRealWorld魔法 我可以想象状态 也可以想象 RealWorld 以某种方式放入 IO 中 但每次我写一个类型签名ST the sST monad 的
  • 如何打乱列表?

    如何从一组数字 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
  • 关于“没有绑定的类型签名”的错误

    我在 Haskell 中遇到 ASCII 问题 fromEnum Char gt Int toEnum Int gt Char offset Int offset fromEnum A fromEnum a toUpper Char gt
  • 在另一个字符串中查找子字符串的索引 Haskell

    我要创建一个带有两个参数 字符串 的函数 该函数应查看第一个参数是否是第二个参数的子字符串 如果是这种情况 它将返回每个出现的元组 其中包含子字符串的起始索引和子字符串的结尾索引 例如 f String gt String gt Int I
  • 如何在haskell中用另一个字符串替换一个字符串

    我想用不同的字符串替换输入文件中的字符串 我正在寻找一种方法 但似乎我只能逐个字符地更改字符串 例如在我下面的代码中 replace String gt String replace replace x xs if x then y rep
  • Haskell 项目可以使用 cmake 吗?

    我正在计划一个用 Haskell 编写的项目 也许也有一些部分是用 C 编写的 对于构建系统 我决定不选择 Haskell 程序 cabal 的常见选择 主要是因为我想了解其他语言的构建程序是如何工作的 我听说过 CMake 我认为这是一个
  • 树莓派 2 上的 GHCi?

    我正在开发一些在 raspberry pi 2 上运行的 haskell 项目 以及可以使用 raspbian 7 4 1 中的 apt get 安装的 ghc 版本 但它没有 GHCi 这会阻止一些重要的包 如 Vector 的编译 我看
  • Parsec.Expr 具有不同优先级的重复前缀

    Parsec Expr buildExpressionParser 的文档说 相同优先级的前缀和后缀运算符只能出现一次 即 如果 为前缀否定 则不允许使用 2 但是 我想解析这样的字符串 具体来说 考虑以下语法 sentence ident
  • 在 ghci 下执行 `(read "[Red]") :: [Color]` 时会发生什么?

    我正在阅读以下小节现实世界 Haskell 第 6 章 类型类 http book realworldhaskell org read using typeclasses html关于一个实例Read for Color 它实现了reads
  • 自定义 monad 的 MonadTransControl 实例

    的文档monad control提供有关如何创建实例的示例MonadTransControl using defaultLiftWith and defaultRestoreT 该示例适用于以下情况newtype newtype Count
  • 由于垃圾收集,Haskell 程序中会出现多长时间的暂停?

    关于我的另一个问题Haskell 集合可以保证每个操作的最坏情况范围 https stackoverflow com q 12393104 1333025 我很好奇 垃圾收集会导致多长时间的暂停 Haskell 是否使用某种增量垃圾收集 以
  • Python 比编译的 Haskell 更快?

    我有一个用 Python 和 Haskell 编写的简单脚本 它读取包含 1 000 000 个换行符分隔的整数的文件 将该文件解析为整数列表 对其进行快速排序 然后将其写入已排序的不同文件中 该文件与未排序的文件具有相同的格式 简单的 这
  • 来自数据类型的 Haskell 随机数

    我对 Haskell 还很陌生 我有一个数据类型 data Sentence Prop Int No Sentence And Sentence Or Sentence deriving Eq 我已经为它写了一个 Show 实例 然而 无论
  • 为什么 GHC 在这里推断出单态类型,即使禁用了单态限制?

    这是由解析 f f pure 的类型 https stackoverflow com questions 55388119 resolving the type of f f pure 55388309 noredirect 1 comme

随机推荐

  • Reactjs :状态的 ShouldComponentUpdate

    我该如何使用shouldComponentUpdate对于各州 我可以检查 shouldComponentUpdate nextProps nextState return this state value nextState value
  • 找不到函数plot.gam

    我正在阅读 R 中应用统计学习简介 ISLR 我被困在第 295 页上的部分 即广义加性模型实验室 当我运行以下代码时出现错误Error in plot gam gam1 se TRUE col red could not find fun
  • 如何在 Intellitrace Events 中跟踪异步数据库操作?

    我正在尝试查看我的应用程序使用的一些查询实体框架做 在我的方法中不是async我可以正常看到查询 public List
  • 如何获取 msbuild.exe?未安装VS2008时可以构建.vcproj吗?

    我知道如果我安装 Visual Studio 2005 或 2008 将会安装 msbuild 我知道如果我安装 NET Framework SDK 也会安装 msbuild 从 NET 3 0开始 我认为不再有单独的 NET Framew
  • Crontab 无法在 Mac OS 上运行 python

    我已经找到了我能找到的每一个答案并尝试了一切 但我仍然无法让我的 crontab 运行 python 我什至创建了一个 shell 脚本来运行 python 认为隔离会有所帮助 但它仍然不起作用 我在 crontab 中有以下条目 echo
  • 如何只输出第一行的git日志?

    我正在尝试自定义格式git log 我希望所有提交都显示在一行中 每行应该只显示提交消息的第一行 I 发现 http book git scm com 3 reviewing history git log html that git lo
  • 图像背景透明GIMP [关闭]

    Closed 这个问题是无关 help closed questions 目前不接受答案 我有一些 jpg 图像 我需要有一个透明的背景 我将在网页中添加这些图像 并且我只需要查看图像的主要元素和下面的网页 有谁知道如何将图像转换为透明背景
  • ModelMapper:根据Child类选择映射

    TL DR 我想以从 AbstractParent 映射到 AbstractParentDTO 的方式使用 modelMapper 然后在 ModelMapper Config 中调用每个子类的特定映射器 然后跳过其余的 抽象类 映射 这怎
  • 为什么我收到 jQuery“ui.element 未定义”错误?

    我有以下内容 widgets ul sortable connectWith widgets ul opacity 0 7 start function e ui fromWidgetPosition ui item prevAll len
  • 有什么方法可以让 CSS 嵌套时可见性起作用吗?

    所以我一直认为如果父容器设置了属性 它就会取代子容器 因此 就我而言 我希望隐藏父容器 但子元素的可见性为可见 但似乎子元素的可见性属性取代了父元素 因此仍然会显示 但问题是 如果使用显示属性 它会按照我想要的方式工作 这是 HTML di
  • 检测 CAShapeLayer 触摸

    我通过覆盖绘制矩形创建了一个蜘蛛图 我使用核心图形 CAShapeLayer 来绘制我的区域 屏幕上创建了多个 CAShapeLayer 区域 我想检测当用户触摸时触摸了哪一层 但是我不明白怎么办 首先 您不应该在 drawRect 中绘制
  • git pull --rebase 导致意外的图表

    我在分行工作 foo 我没有未分阶段的更改 没有工作更改 完全干净的状态 其中HEAD foo origin foo根据我的盒子 git status On branch foo Untracked files use git add
  • 使用 Python 重命名目录中的一堆文件时出现问题

    import os def rename files file list os listdir r G Python Learning prank print file list saved path os getcwd print Cur
  • 仅当 JavaScript 中的三元运算符中条件为 true 时才进行赋值

    在 JavaScript 中可以做这样的事情吗 max max lt b b 换句话说 仅当条件为真时才赋值 如果条件为假 则不执行任何操作 不赋值 这可能吗 不要使用三元运算符 https developer mozilla org en
  • 使用 php mysql jquery ajax 更新选择框的值

    我在改变方面面临重大问题status in
  • jvm中的Java对象ID

    调试时 Eclipse 中的对象值附近会显示一个对象 ID 例如 28332是会话对象的ID 另一个例子 waiting for id 101 显示在 调试 面板中 这些 ID 既不是哈希码也不是System identityHashCod
  • 在 Colaboratory 中保存变量状态

    当我运行一个协作实验室中的 Python 脚本 https drive google com file d 1aHl XTDhs24XQ4qcdTgkk2cfF3iatpxj view usp sharing 它正在运行所有以前的代码单元
  • 在 Spring 服务类的所有实例之间共享一个 hashmap 实例

    我打算创建一个实时计数器 因此 一个用户可以增加特定键的计数器值 而另一个则通过 ajax 请求 在循环中或使用某种长轮询方法 获取更新的计数值 我将使用 spring 控制器 它将注入服务类我可以执行如下操作 还是有更好的方法 Servi
  • ASP.NET (OWIN) Identity:如何从 Web API 控制器获取 UserID?

    使用VS2013 RTW ASP NET MVC5 我看过很多有关如何在使用 ASP NET 身份时向 ApplicationUser 类 和表 添加属性的文档 但我还没有看到任何关于如何拥有一个单独的表 其内容通过外键映射到 Applic
  • 如何在类型级别用可选字段表示数据?

    我正在研究具有值 多态 可以是任何值 的控制流数据 而且它也could有一个验证器函数来检查该值是否仍然有效 并且could有一个 刷新值 的函数 返回具有新值的新数据 在 vanilla Haskell 中它可以看起来像这样 data M