Haskell——有什么方法可以限定记录名称或消除记录名称的歧义吗?

2023-12-19

我有两种数据类型,用于hastache模板。在我的代码中,有两种不同的类型是有意义的,两者都有一个名为“name”的字段。这当然会引起冲突。似乎有一种机制可以消除对“名称”的任何调用的歧义,但实际的定义会引起问题。是否有任何解决方法,例如让记录字段名称合格?

data DeviceArray = DeviceArray
    { name :: String,
      bytes :: Int }
    deriving (Eq, Show, Data, Typeable)

data TemplateParams = TemplateParams
    { arrays :: [DeviceArray],
      input :: DeviceArray }
    deriving (Eq, Show, Data, Typeable)

data MakefileParams = MakefileParams
    { name :: String }
    deriving (Eq, Show, Data, Typeable)

即,如果这些字段现在在代码中使用,它们将是“DeviceArray.name”和“MakefileParams.name”?


正如已经指出的,这不可能直接实现,但我想就建议的解决方案说几句话:

如果这两个字段是明显不同,无论如何你都会想知道你正在使用哪个。这里所说的“明显不同”是指在任何情况下都不可能对任何一个领域做同样的事情。鉴于此,过度的歧义并不是真正不受欢迎,所以你想要合格进口作为标准方法,或字段消歧扩展如果这更符合您的口味。或者,作为一个非常简单(并且有点难看)的选项,只需手动为字段添加前缀,例如deviceArrayName而不是仅仅name.

如果这两个字段在某种意义上是一样的东西,能够以同质的方式对待它们是有意义的;理想情况下,您可以编写一个多态函数来选择name场地。在这种情况下,一种选择是使用类型类别对于“命名事物”,具有可让您访问name任何适当类型的字段。这里的一个主要缺点是,除了琐碎类型约束的激增和可怕的单态限制可能带来的麻烦之外,您还失去了使用记录语法的能力,这开始破坏整个要点。

类似字段的另一个主要选项(我还没有看到建议)是提取name字段输出为单个参数化类型,例如data Named a = Named { name :: String, item :: a }. GHC 本身使用这种方法来定位语法树中的源位置 http://www.haskell.org/ghc/docs/latest/html/libraries/ghc/SrcLoc.html#t:Located,虽然它不使用记录语法,但想法是相同的。这里的缺点是如果你有一个Named DeviceArray,访问bytes字段现在需要经过两层记录。如果您想更新bytes带有函数的字段,你会遇到这样的问题:

addBytes b na = na { item = (item na) { bytes = b + bytes (item na) } }

啊。有一些方法可以稍微缓解这个问题,但在我看来,它们仍然不是主意。像这样的情况就是我一般不喜欢记录语法的原因。因此,作为最后的选择,一些哈斯克尔模板魔法和the fclabels package http://hackage.haskell.org/package/fclabels:

{-# LANGUAGE TemplateHaskell #-}

import Control.Category
import Data.Record.Label

data Named a = Named 
    { _name :: String, 
      _namedItem :: a }
    deriving (Eq, Show, Data, Typeable)

data DeviceArray = DeviceArray { _bytes :: Int }
    deriving (Eq, Show, Data, Typeable)

data MakefileParams = MakefileParams { _makefileParams :: [MakeParam] }
    deriving (Eq, Show, Data, Typeable)

data MakeParam = MakeParam { paramText :: String }
    deriving (Eq, Show, Data, Typeable)

$(mkLabels [''Named, ''DeviceArray, ''MakefileParams, ''MakeParam])

不介意MakeParam生意,我只是需要一个可以做点什么的地方。无论如何,现在您可以像这样修改字段:

addBytes b = modL (namedItem >>> bytes) (b +)
nubParams = modL (namedItem >>> makefileParams) nub

你还可以命名bytes就像是bytesInternal然后导出一个访问器bytes = namedItem >>> bytesInternal如果你喜欢。

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

Haskell——有什么方法可以限定记录名称或消除记录名称的歧义吗? 的相关文章

  • 整数转浮点数

    这段代码的工作原理 posToXY Float gt Float gt Integer posToXY a b do let y a b round y 但这不起作用 posToXY Integer gt Integer gt Intege
  • Haskell Cabal 包 - 找不到 Paths_ 模块

    我正在开发一个 Haskell 项目 Happstack 服务器 Blaze HTML 前端作为主要库 我想添加一个静态数据目录 看起来你可以使用 Cabal 使用自动生成的Path
  • ErrorT 已弃用,但 exceptT 不适合

    我有一个一元计算 在某些时候 由于单子模式匹配 它开始需要 MonadFail 约束 我的简单解决方法是使用以下命令运行它 fmap either error id runErrorT 然而哎呀 Deprecated Use Control
  • 为什么 Parsec 的 sepBy 停止并且不解析所有元素?

    我正在尝试解析一些逗号分隔的字符串 该字符串可能包含也可能不包含具有图像尺寸的字符串 例如 hello world 300x300 good bye world 我写了下面的小程序 import Text Parsec import qua
  • Haskell:无法预期类型“Integer”与实际类型“Int”

    我已经盯着这段代码有一段时间了 但我无法理解该错误消息 divisors Integer gt Integer divisors n t t lt 1 n mod n t 0 length a gt Integer length 0 len
  • Haskell 中的 print 是纯函数吗?

    Is print在 Haskell 中是纯函数 为什么或者为什么不 我认为不是 因为它并不总是返回与纯函数应返回的值相同的值 类型的值IO Int并不是真正的Int 它更像是一张纸 上面写着 嘿 Haskell 运行时 请生成一个Int如此
  • 将两个 Int 值相除以获得 Float 的正确方法是什么?

    我想分两份IntHaskell 中的值并获得结果Float 我尝试这样做 foo Int gt Int gt Float foo a b fromRational a b 但 GHC 版本 6 12 1 告诉我 无法将预期类型 Intege
  • Haskell,堆栈:找到可执行文件

    我正在寻找类似的东西 stack whereis hasktags where whereis行为或多或少类似于 UNIXwhereis命令 hasktags是这样运行的 stack exec hasktags stack exec whe
  • Haskell 入门

    这个问题的答案是社区努力 help privileges edit community wiki 编辑现有答案以改进这篇文章 目前不接受新的答案或互动 几天来 我一直试图理解 Haskell 中的函数式编程范例 我通过阅读教程和观看截屏视频
  • Haskell Stack 从 github 安装包依赖项

    是否可以使用 Haskell 堆栈从 github 安装软件包的版本 例如在一个 cabal or a stack yaml文件 如何在 git repo branch revision 上指向依赖项 对于堆栈 The 的文档stack y
  • 有没有更好的方法将 UTC 时间转换为大纪元时间?

    我想将文件的修改时间设置为从 exif 数据获取的时间 为了从 exif 获取时间 我发现 Graphics Exif getTag Exif gt String gt IO Maybe String 要设置文件修改时间 我发现 Syste
  • 如何在haskell中获取变量名称

    我来到 haskell 时有一些 c 背景知识 想知道是否有类似的 define print a printf s d n a a int a 5 print a 应该打印 a 5 这是 augustss 提到的 TH 解决方案 LANGU
  • 找不到模块“Yesod”

    我有以下代码 LANGUAGE TypeFamilies QuasiQuotes MultiParamTypeClasses TemplateHaskell OverloadedStrings module Simple where imp
  • Haskell 对于 Web 应用程序来说足够成熟吗? [关闭]

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

    Louis Wasserman 编写了当前的实现inits and tails in Data Sequence 他表示它们非常高效 事实上 只要查看代码 我就可以看到 无论它们在做什么 它们都是以干净 自上而下的方式进行的 这往往会给惰性
  • ST monad 是如何工作的?

    我知道 ST monad 有点像 IO 的弟弟 而 IO 又是添加了状态 monadRealWorld魔法 我可以想象状态 也可以想象 RealWorld 以某种方式放入 IO 中 但每次我写一个类型签名ST the sST monad 的
  • 如何在Haskell中实现词法分析器和解析器

    我在这里得到了这段代码 它是用Haskell结构的命令式编程语言编写的程序 所以问题是 我如何为这种语言实现词法分析器和解析器 该程序被定义为一系列语句有 6 种类型 goto write stop if goto 和 int int n
  • 如何打乱列表?

    如何从一组数字 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
  • 类型级别集结合律的证明

    我试图证明类型级函数Union https hackage haskell org package type level sets 0 8 5 0 docs Data Type Set html t Union是关联的 但我不确定应该如何完
  • 我是否需要采取明确的操作来促进与持久数据结构的共享?

    我来自命令式背景 正在尝试实现一个简单的不相交集 并集查找 数据结构 以获得在 Haskell 中创建和修改 持久 数据结构的一些练习 目标是有一个简单的实现 但我也关心效率 我的问题与此相关 首先 我创建了一个按等级并集的不相交集森林实现

随机推荐