Haskell 中 Idris 的 Fin 的首选替代方案是什么

2023-12-21

我想要一个可以包含 0 到 n 值的类型,其中 n 位于类型级别。

我正在尝试类似的事情:

import GHC.TypeLits
import Data.Proxy

newtype FiniteNat n = FiniteNat { toInteger :: Integer }

smartConstructFiniteNat :: (KnownNat n) => Proxy n -> Integer -> Maybe (FiniteNat (Proxy n))
smartConstructFiniteNat pn i 
  | 0 <= i && i < n = Just (FiniteNat i)
  | otherwise       = Nothing
  where n = natVal pn

基本上可以工作,但不知何故并不真正令人满意。是否有一个“标准”解决方案,甚至是一个库来实现这一目标?关于依赖类型列表长度有很多争论,但我无法找到确切的东西。另外 - 我假设使用GHC.TypeLits是必要的,因为我的n可以取相当大的值,因此归纳定义可能会非常慢。


你可以直接翻译伊德里斯的Fin成通常的 Haskell 的依赖类型特征的混杂。

data Fin n where
    FZ :: Fin (S n)
    FS :: Fin n -> Fin (S n)

(!) :: Vec n a -> Fin n -> a
(x :> xs) ! FZ = x
(x :> xs) ! (FS f) = xs ! f

With TypeInType你甚至可以有单身人士Fins!

data Finny n (f :: Fin n) where
    FZy :: Finny (S n) FZ
    FSy :: Finny n f -> Finny (S n) (FS f)

这可以让你伪造运行时相关的量化, eg,

type family Fin2Nat n (f :: Fin n) where
    Fin2Nat (S _) FZ = Z
    Fin2Nat (S n) (FS f) = S (Fin2Nat n f)

-- tighten the upper bound on a given Fin as far as possible
tighten :: Finny n f -> Fin (S (Fin2Nat n f))
tighten FZy = FZ
tighten (FSy f) = FS (tighten f)

但是,呃,必须在值和类型级别复制所有内容,并写出所有类型变量,这有点糟糕(n)可能会变得非常乏味。


如果您确实确定需要有效的运行时表示Fin,你基本上可以做你在问题中所做的事情:填充机器Int into a newtype并使用幻像类型作为其大小。但作为库的实现者,你有责任确保Int符合界限!

newtype Fin n = Fin Int

-- fake up the constructors
fz :: Fin (S n)
fz = Fin 0
fs :: Fin n -> Fin (S n)
fs (Fin n) = Fin (n+1)

此版本缺少真正的 GADT 构造函数,因此您无法使用模式匹配来操作类型相等性。你必须自己使用unsafeCoerce。您可以为客户端提供以下形式的类型安全接口fold,但他们必须愿意以高阶风格编写所有代码,并且(因为fold是一种变形现象),一次观察多个层变得更加困难。

-- the unsafeCoerce calls assert that m ~ S n
fold :: (forall n. r n -> r (S n)) -> (forall n. r (S n)) -> Fin m -> r m
fold k z (Fin 0) = unsafeCoerce z
fold k z (Fin n) = unsafeCoerce $ k $ fold k z (Fin (n-1))

哦,你不能进行类型级计算(就像我们所做的那样)Fin2Nat上面)用这个表示Fin,因为类型级别Ints 不允许感应。

就其价值而言,伊德里斯Fin与上面的 GADT 一样效率低下。该文档包含以下警告 https://github.com/idris-lang/Idris-dev/blob/29e271c8dd6af842817156cdb17e203e401b0899/libs/base/Data/Fin.idr#L8-L9:

使用它可能不是一个好主意Fin对于算术来说,它们在运行时效率极低。

我听说伊德里斯的未来版本能够识别“Nat具有类型”风格的数据类型(例如Fin)并自动删除证明并将值打包到机器整数中,但据我所知,我们还没有做到这一点。

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

Haskell 中 Idris 的 Fin 的首选替代方案是什么 的相关文章

  • 整数转浮点数

    这段代码的工作原理 posToXY Float gt Float gt Integer posToXY a b do let y a b round y 但这不起作用 posToXY Integer gt Integer gt Intege
  • 访问函数中的环境

    In main我可以读取我的配置文件 并将其提供为runReader somefunc myEnv正好 但somefunc不需要访问myEnv读者提供 链中的下一对也没有提供 需要 myEnv 中某些内容的函数是一个微小的叶函数 如何在不将
  • 为什么 Parsec 的 sepBy 停止并且不解析所有元素?

    我正在尝试解析一些逗号分隔的字符串 该字符串可能包含也可能不包含具有图像尺寸的字符串 例如 hello world 300x300 good bye world 我写了下面的小程序 import Text Parsec import qua
  • 在 Haskell 中计算移动平均线

    我正在学习 Haskell 所以我尝试实现移动平均函数 这是我的代码 mAverage Int gt Int gt Float mAverage x a fromIntegral k fromIntegral x k lt rawAvera
  • Haskell 中的实例声明

    我有这两个功能 primes sieve 2 where sieve p xs p sieve x x lt xs x mod p gt 0 isPrime number number 1 null x x lt takeWhile x g
  • 在 Haskell 中增长数组

    我想在 Haskell 中实现以下 命令式 算法 给定一个序列对 e0 s0 e1 s1 e2 s2 en sn 其中 e 和 s 部分不一定是自然数不同的是 在每个时间步都会随机选择该序列的一个元素 例如 ei si 并根据 ei si
  • Haskell 类型系统的细微差别

    我一直在深入了解 haskell 类型系统的本质 并试图了解类型类的要点 我已经学到了很多东西 但我在下面的代码片段上遇到了困难 使用这些类和实例定义 class Show a gt C a where f Int gt a instanc
  • 无点镜头创建不进行类型检查

    在函数中test 我遍历一个列表 从它的成员生成镜头 然后打印一些数据 当我使用有针对性的呼叫风格时 这会起作用 当我使其成为无点时 它无法进行类型检查 为什么会出现这种情况 我该如何解决这个问题 在我看来 GHC 并没有保留排名较高的信息
  • Haskell 下划线与显式变量

    我已经学习 Haskell 几个星期了 我有一个关于下划线的使用的问题 作为函数参数 我认为用一个具体的例子来问我的问题会更好 假设我想定义一个函数 根据提供的索引提取列表的元素 是的 我意识到 已经是预先定义的 我可以定义该函数的两种方法
  • 在依赖类型的函数式编程语言中,扁平化列表是否更容易?

    在 haskell 中寻找一个可以展平任意深度嵌套列表的函数时 即应用的函数concat递归并在最后一次迭代时停止 使用非嵌套列表 我注意到这需要有一个更灵活的类型系统 因为随着列表深度的变化 输入类型也会变化 确实 有几个 stackov
  • Haskell,堆栈:找到可执行文件

    我正在寻找类似的东西 stack whereis hasktags where whereis行为或多或少类似于 UNIXwhereis命令 hasktags是这样运行的 stack exec hasktags stack exec whe
  • 以下两个 lambda 函数的空间复杂度

    我正在阅读以下内容 https en wikibooks org wiki Haskell Graph reduction https en wikibooks org wiki Haskell Graph reduction 其内容如下
  • Haskell 泛化问题(涉及列表理解)

    假设我想知道a上的所有要点 x y 矩形内的平面has 我可以使用列表推导式来计算 如下所示 let myFun2D x y x lt 0 2 y lt 0 2 现在 如果我想为一个人完成同样的事情 x y z 空间 我可以采取同样的方式并
  • Haskell 中的中缀运算符优先级

    对于以下 Haskell 表达式 返回 a gt gt f 应该读作 返回a gt gt f or 返回 a gt gt f 这里的相关规则是什么 规则始终是函数应用程序的优先级高于任何运算符 因此 return a gt gt f 被解析
  • Haskell 入门

    这个问题的答案是社区努力 help privileges edit community wiki 编辑现有答案以改进这篇文章 目前不接受新的答案或互动 几天来 我一直试图理解 Haskell 中的函数式编程范例 我通过阅读教程和观看截屏视频
  • 如何在haskell中获取变量名称

    我来到 haskell 时有一些 c 背景知识 想知道是否有类似的 define print a printf s d n a a int a 5 print a 应该打印 a 5 这是 augustss 提到的 TH 解决方案 LANGU
  • Data.Sequence 中的 inits 和 tails 如何工作?

    Louis Wasserman 编写了当前的实现inits and tails in Data Sequence 他表示它们非常高效 事实上 只要查看代码 我就可以看到 无论它们在做什么 它们都是以干净 自上而下的方式进行的 这往往会给惰性
  • 带有 RankNTypes 扩展的奇怪类型推断

    我正在尝试在 Haskell 中尝试 System F 类型 并通过以下方式实现了自然数的 Church 编码type 当加载这段代码时 OPTIONS GHC Wall LANGUAGE RankNTypes type CNat fora
  • 检查对以下内容的理解:“变量”与“变量” “价值”、“功能”与“抽象”

    这个问题是后续问题this one https stackoverflow com questions 25327705 is function a sort of variable 25329157 25329157在学习 Haskell
  • 如何在Haskell中实现词法分析器和解析器

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

随机推荐

  • Java 数组 Setter Getter

    有人可以帮我解决一个小问题吗 例如 我想为 1 名学生设置 3 个讲座 但是当我尝试此操作时 我无法设置讲座 student setStudentLecture lecture student setStudentLecture lectu
  • Android在openstreetmap上绘制路线[关闭]

    Closed 这个问题需要多问focused help closed questions 目前不接受答案 我正在寻找一种方法来绘制路线路径openstreetmap在我的 Android 应用程序中 我只有起点和终点 但不想要一条直线 关于
  • SF 符号在 SwiftUI 中调整为相同大小看起来不正确

    我在我的应用程序中显示一排各种 SF 符号 并希望将它们的大小调整为按钮 然而 由于 SF 符号一开始的大小并不相同 当我将它们全部调整到 44x44 时 有些符号显得太大 我可以根据它们的内容来调整它们的大小 但是我实际上不知道这些符号会
  • 如何将 jquery ajax 转换为原生 javascript?

    这是我的 ajaxHandler 我想将其转换为本机 javascript 即 使用 XMLHttpRequest 但我无法理解如何转换 ajaxHandler defaultAttributes type GET url index ph
  • vue 实例和 vue 组件之间的区别?

    我是vue js新手 在学习时有一些疑问 我现在对其实例和组件之间的关系有点困惑 据我所知 vue 构建的每个应用程序都应该只有一个实例 并且只有一个实例 如果需要 它可以有任意多个组件 但最近我看到了一个演示 在该演示中它有多个实例 所以
  • org.gdal.ogr.ogrJNI.GetDriverCount() 引起的 UnsatisfiedLinkError

    我正在 Windows 7 上使用 Eclipse Luna 使用 Java 进行开发 我正在将 gdal 用于某些 ogr 进程 并且从 eclipse 运行该应用程序没问题 但在同一台计算机上从命令行运行会遇到问题 我得到以下信息 Ca
  • Google App Engine Python、virtualenv 和 mimetypes

    我有使用 djangoappengine 构建并在 App Engine 开发服务器下运行的工作项目 所以我运行 manage py runserver 并且一切正常 所有需求 django djangoappengine 等 都位于项目根
  • igraph 和 tnet 之间中心性度量的差异

    我正在尝试获取有向加权网络的中心性度量 我一直在使用igraph and tnet包在R 然而 我发现使用这两个包获得的结果存在一些差异 并且我对这些差异的原因有点困惑 见下文 require igraph require tnet set
  • Android Studio 卡在“下载组件”上

    我已经安装了 android studio 当我想下载像sdk经理等 我被困在这里 像这样 我遇到了完全相同的问题 在反复看到这些不具有描述性的下载后 我感到沮丧 此外 在高速互联网上下载也需要花费大量时间 只需等待它就会完成
  • AlertController 不在窗口层次结构中

    我刚刚使用 ViewController 类创建了一个单视图应用程序项目 我想从位于我自己的类中的函数显示 UIAlertController 这是我的带有警报的班级 class AlertController UIViewControll
  • 将 DLL 拖放到 Windows Server 2008 .net 4.0 中的 GAC(“程序集”)

    我试图将一些代码部署到客户端计算机 但我不想在客户端计算机上安装 MS Windows SDK 工具 这意味着无权访问 gacutil 我还没有为我的代码创建安装程序 看起来这可能是 net 4 0 中仅有的两个选项 在过去 我只需启动 运
  • 在自定义 ViewModel 中重用验证属性

    当我开始使用时xVal http xval codeplex com 对于客户端验证 我仅实现使用域模型对象作为视图模型或视图模型中这些对象的嵌入实例的操作方法 这种方法在大多数情况下都可以正常工作 但在某些情况下 视图需要仅显示和回发模型
  • 如何禁用 tableView 中表列的重新排序?

    试图弄清楚如何禁用 javafx 2 中表列的重新排序 这是解决方案 tblView getColumns addListener new ListChangeListener Override public void onChanged
  • 找不到元素“beans”的声明

    我有弹簧罐spring 3 2 0 RC1 jar并试图实施Apache ActiveMQ helloWorld给出的教程中的程序here http icodingclub blogspot com 2011 07 introduction
  • 如何获取枚举的数值?

    假设你有 public enum Week SUNDAY MONDAY TUESDAY WEDNESDAY THURSDAY FRIDAY SATURDAY 一个人怎样才能得到int表示星期日是 0 星期三是 3 等 Week week W
  • 静态库依赖项在 Xcode 3.2.3 上的模拟器中编译,在设备上失败

    升级到 XCode 3 2 3 和 iPhone 3 2 4 0 SDK 在我的构建过程中引入了一个奇怪的错误 我有一个静态库 Compton 它本身依赖于 Three20 我将 Compton 构建为它所支持的客户端应用程序的依赖项 当我
  • MySQL POINT空间索引查询以中心POINT为半径范围内

    我看到许多解决方案可以从 a 中获取最近的行POINT转换为X and Y 并对距离进行三角计算 据我了解 这似乎没有利用空间索引 从最常见的意义上来说 如何利用空间索引 返回其空间索引的行POINT位于中心的半径范围内POINT 换句话说
  • NODEJS:立即发送文件和数据

    这就是我得到的 它工作得很好 但我希望能够在客户端登录我的网站时向他发送文件和数据 JSON 有什么办法可以结合起来吗 app get function req res res sendfile dirname index html 您无法
  • mysql联合结果中的错误列

    使用 union 时我得到了错误的列名称 这就是我所做的 我有两个非常大的表 具有相同的结构和不同的记录 所以就是这样 mysql gt select from e18 where 15 like car limit 1
  • Haskell 中 Idris 的 Fin 的首选替代方案是什么

    我想要一个可以包含 0 到 n 值的类型 其中 n 位于类型级别 我正在尝试类似的事情 import GHC TypeLits import Data Proxy newtype FiniteNat n FiniteNat toIntege