haskell - 从 Haskell 的列表中构造一个依赖类型
问题描述
我想在 Haskell 中为 Galois 字段编写一个库。伽罗瓦域由其不可约多项式定义。只有当它们具有相同的伽罗瓦域时,才能添加伽罗瓦域元素。我想将多项式提升为我的 Galois 域的类型,例如,具有多项式 [1, 2, 3] 的 Galois 域与具有多项式 [2, 0, 1] 的 Galois 域具有不同的类型。这样我可以确保只能添加具有相同 Galois 域的 Galois 域元素。这可能吗?
我的多项式数据类型如下所示:
newtype Polynomial a = Polynomial [a]
我的 Galois 字段数据类型如下所示:
data GF irr a = GF {
irreducible :: irr
, q :: PrimePower
}
所以我想要一个构造函数,它采用多项式(例如(Polynomial [2, 0, 1])
)并给我一个类型的 Galois 字段GF (Polynomial Int) ([2, 0, 1])
。我知道这[2, 0, 1]
不是一个有效的类型,但我看到使用Data.Singletons可以创建类似的类型
(SCons STrue (SCons SFalse SNil))
for [True, False]
,但我不知道如何从我的列表中构造这些类型[2, 0, 1]
以及构造函数的外观。
解决方案
正如卢克已经评论的那样,[2, 0, 1]
实际上是一个有效的类型。
Prelude> :set -XDataKinds -XPolyKinds
Prelude> data A x = A deriving Show
Prelude> A :: A [2,0,1]
A
其中数字字面量实际上是类型级别的Nat
字面量,并且[...]
是类型类型的列表值构造函数的提升版本。这可以通过使用“prime-quote syntax”来明确表达</p>
Prelude> A :: A '[2, 0, 1]
A
...所以,这个任务实际上是微不足道的。你可以使用
{-# LANGUAGE DataKinds, KindSignatures #-}
import GHC.TypeLits (Nat)
newtype Polynomial a = Polynomial [a]
data GF (irr :: Polynomial Nat) = GF {q :: PrimePower}
正如 Luke 所说,请记住,尽管类型级别的计算不如在完全依赖类型的语言中工作得好。如果你真的想用这个做证明,你应该考虑改用 Idris、Agda 或 Coq。
推荐阅读
- node.js - makeExecutableSchema 上的语法错误:意外的名称“用户”(GraphQL)
- algorithm - 获取列表列表的类似笛卡尔积,长度不等,并且对每个项目应用函数('a -> 'b 列表)
- php - 使用 VSCode 和 Docker 调试 PHP
- google-cloud-platform - 日志输出int的值有错误
- entity-framework - 如何在实体框架 LINQ 中格式化数字(不带尾随零)?
- php - PHP 7.2 - 如何在字符串中有函数体时动态创建匿名函数
- php - PHP Rand 函数似乎是加权的
- python - 绘制具有不同颜色的多个值的字典
- math - 缩小一个圆,同时保持所有点在里面
- jquery - 单击下一个链接