递归函数依赖不起作用

2024-01-27

我正在尝试乘以单位数组(来自dimensional)在幻像类型中,我在功能依赖性方面遇到了麻烦。问题的简化版本如下:

我有以下类型

data F (a:: [*]) = F String

其中字符串表示外语表达式,幻像类型表示类型列表。

我可以做类似的事情

x = F "x" :: F '[Double]
y = F "(1,3)" :: F '[Int, Int]

我设法通过创建一个来实现这样的算术运算符Nums类是一个列表Num.

class Nums (a::[*])
instance Nums '[]
instance (Num a, Nums as) => Num (a ': as)

然后我可以实例化Num F

instance Nums as => F as where
   (F a) * (F b) = F (a ++ "*" ++ b)
   ... etc ...

现在,我尝试使用物理单位做同样的事情。我可以用这种方式用一种类型的列表来做到这一点

import qualified Numeric.Units.Dimensional as Dim

data F (a::[*]) = F String
(!*!) :: (Num n, Dim.Mul a b c) => F '[Dim.Dimensional v a n]
                                -> F '[Dim.Dimensional v b n]
                                -> F '[Dim.Dimensional v c n]

(F a) !*! (F b) = F (a ++ "*" ++ b)

这似乎有效,我可以“乘以”不同单位的 2 'F,结果在正确的单位中。 显然,我想将其推广到任何列表并使用与Nums我称之为Muls.

class Muls a b c | a b -> c
instance '[] '[] '[]
instance (Num n, Mul a b c, Muls as bs cs) 
   => Muls (Dim.Dimensional v a n ': as)
           (Dim.Dimensional v b n ': bs)
           (Dim.Dimensional v c n ': cs)

!*! :: (Muls as bs cs) => F as -> F bs -> F cs
(F a) !*! (F b) = F (a ++ "*" ++ b)

我得到了一个Illegal Instance declaration error :

Illegal instance declaration for
 ‘Muls
    (Dim.Dimensional v a n : as)
    (Dim.Dimensional v b n : bs)
    (Dim.Dimensional v c n : cs)’
 The coverage condition fails in class ‘Muls’
   for functional dependency: ‘a b -> c’
 Reason: lhs types ‘Dim.Dimensional v a n : as’, ‘Dim.Dimensional
                                                    v b n
                                                    : bs’
   do not jointly determine rhs type ‘Dim.Dimensional v c n : cs’
 Using UndecidableInstances might help
In the instance declaration for
 ‘Muls (Dim.Dimensional v a n : as) (Dim.Dimensional v b n
                                    : bs) (Dim.Dimensional v c n : cs)’

如果我使用UndecidableInstances扩展,看起来确实有效。我的问题是,为什么我需要这个扩展,有什么办法可以避免它?

或者,我可能可以使用类型系列版本来完成此工作dimensional。不幸的是,我需要自定义单位,但不清楚是否dimensional-tf支持用户定义的单位。


默认情况下,Haskell 要求实例选择是可判定的,即尝试判定类型是否满足约束不会导致编译器中出现无限循环。考虑以下代码:

class A (a :: *)
class B (a :: *) 
instance A a => B a 

这个明显的例子could导致无限循环(它不一定会这样做!)。即使每个其他实例本身都不会导致无限循环,但添加此实例却可以。某处可能有严格的证明,但我不知道。

唯一的事情UndecidableInstances确实是说“我保证我永远不会使用导致无限循环的类型来调用我的函数,因此即使我的实例可以产生无限循环,我也有责任确保这种情况不会发生。”

另一方面,形式的实例:

instance (C1 a1, C2 a2 ... Cn an) => C (T a1 a2 .. an)

永远不会产生无限循环,因为 Haskell 不允许无限类型,并且此实例解包单个构造函数,因此即使Ci回指C你最终会得到一个有 0 个类型参数的类型构造函数。

如果你编写一个不可判定的实例,你should get

test.hs:26:10:
    Constraint is no smaller than the instance head
      in the constraint: A a
    (Use UndecidableInstances to permit this)
    In the instance declaration for `B a'

我认为这是您在您的情况下应该看到的错误,并且显示您实际看到的错误应该被视为错误。

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

递归函数依赖不起作用 的相关文章

随机推荐

  • 如何让表单元素“记住”选择?

    我现在正在使用 php 构建一个 更改分类 页面 我使用Mysql作为数据库 目前我使用PHP来获取有关分类的所有mysql信息 然后我像这样输出 table
  • Microsoft Edge 的 URL 长度限制

    有人知道 Microsoft Edge 的 URL 长度限制吗 如您所知 Internet Explorer 对 URL 长度有限制 最大长度为 2048 Edge 怎么样 我想 现在应该已经消失了 极限似乎已到81578 个字符 之后 我
  • 如何使用Ramda管道?

    背景 我正在尝试使用 Ramda 编写 2 个函数 但我遇到了问题pipe 这意味着我不知道如何使用它 Code 假设我有一个返回数组的函数 var createQuery params gt getSQLQuery params getM
  • 断言失败:电影播放器​​的激活状态错误 (1)

    我正在 iPad 应用程序的一个页面上播放视频 m4v 然后它会转到另一个视图控制器来播放另一个视频 它播放正常 但是当第二个视频播放完毕时 它会抛出断言失败 错误是 Assertion failure in MPMoviePlayerCo
  • Getx Flutter - 更新列表中的项目不是反应性的

    我使用 getx 作为我的 flutter 应用程序的状态管理 但我在更新列表中的值时遇到困难 所以我有一个参数为 isFollowing 的用户模型 当我单击按钮时 isFollowing 变量将发生变化并且颜色也应更新 但这并没有发生
  • 放置 libgdx Screen 的正确位置在哪里

    您好 我正在开发一款游戏 我想知道如何处理资源 因为我遇到了内存问题 我有这样的事情 public SplashScreen implements Screen Override public void render float delta
  • Flexbox - 垂直居中并匹配大小

    我使用 Flex 有两个相邻的按钮 并且它们的内容垂直居中 到目前为止效果很好 但是 当在移动页面上查看我的网站时 使用响应式设计来缩放页面 第二个按钮 其中的文本较少 的大小会与其同伴的大小不同 因此 目标是垂直对齐按钮上的文本 并使两个
  • 投票 - 阻止客户端滥用 - ASP.NET MVC

    所以我设计了这个投票的东西 它不会让某人在 24 小时内为同一篇文章投票两次 然而 假设一个人投票 并且在看到该人能够投票或者他处于 24 小时窗口内之后 我禁用投票按钮 顺便说一句 这都是 Ajax 但是 当一个人关闭浏览器并重新打开甚至
  • tsql函数分割字符串

    我想知道是否有人可以帮助我 我需要一个 sql 函数来分割给定值 例如 1 00 Not specified 3 01 05 Global WM BB Operations 2 02 05 01 Global WM BB Operation
  • 从 Eclipse PDT 转换为 Vim [关闭]

    Closed 此问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 我真的很喜欢 VIM 它是我遇到过的少数几个能让你内心感到温暖和模糊的应用程序之一 然而 对于 PHP
  • 如何在 thenOpen 中获取 casper.js 中的响应状态 404 而不是 undefined?

    知道为什么下面的代码在任何一个中都没有捕获 404responsevar 或在http status 404 event 我使用 phantomjs 1 9 casperjs 1 0 2 和 Windows 7 运行此程序 var casp
  • 是否可以对 Xcode 项目的“构建阶段”部分中的“编译源”列表进行排序?

    我想根据名称对 Xcode 项目的 编译源 部分中的文件进行排序 是否可以 是的 您可以重新订购编译源Xcode 中的部分 但不是 GUI 中的部分 考虑到这已经是 IDE 的第 6 版 而且他们仍然没有解决这个基本功能 这很遗憾 正如 A
  • 如何在 Meteor Spacebars 模板中重复块 N 次?

    我在空格键模板中有这段代码 1
  • Lubridate 未在 R 中正确将日期时间转换为 POSIXct (dd/mm/yy hh:mm:ss) [关闭]

    Closed 这个问题是无法重现或由拼写错误引起 help closed questions 目前不接受答案 我正在尝试将日期时间从 csv 转换为 POSIXct 以进行数据分析 我已经尝试了多个代码 但要么得到 NA 要么格式错误 我当
  • pandas:根据另一个数据框的列选择数据框列

    我正在尝试对 a 进行子集化pandas基于另一个类似数据框中的列的数据框 我可以在 R 中轻松做到这一点 df1 lt data frame A 1 5 B 6 10 C 11 15 df2 lt data frame A 1 5 B 6
  • 使用队列的生产者/消费者线程

    我想创建某种Producer Consumer线程应用程序 但我不确定在两者之间实现队列的最佳方法是什么 所以我有两个想法 这两个想法都可能是完全错误的 我想知道哪个更好 如果它们都很糟糕那么实现队列的最佳方法是什么 我关心的主要是这些示例
  • 如何让 Microsoft C++ 编译器将未知标志视为错误而不是警告?

    出于各种原因 我希望能够编写脚本来检测 MS C 编译器是否支持特定标志 我正在使用 Windows 7 1 SDK 中的编译器 C gt cl version Microsoft R C C Optimizing Compiler Ver
  • JavaScript 中的跨域数据访问

    我们有一个 ASP Net 应用程序托管在我们的网络上并暴露给特定的客户端 该客户希望能够将数据从他们自己的服务器导入到我们的应用程序中 数据通过 HTTP 请求检索 并采用 CSV 格式 问题是他们不想将他们的服务器暴露给我们的网络 并请
  • 在 JavaFX 中调整选项卡内容的大小

    老实说 我对 JavaFX 以及 Java 中的任何 UI 开发都是完全陌生的 我正在使用 fxml 来定义我的屏幕布局 我想要一个使用选项卡的应用程序 第一个选项卡的内部布局与 IssueTracker 示例应用程序非常相似 我创建了下面
  • 递归函数依赖不起作用

    我正在尝试乘以单位数组 来自dimensional 在幻像类型中 我在功能依赖性方面遇到了麻烦 问题的简化版本如下 我有以下类型 data F a F String 其中字符串表示外语表达式 幻像类型表示类型列表 我可以做类似的事情 x F