如何从范围内的约束族派生类型类实例?

2024-01-12

edit:我又跟进了一个具体问题 https://stackoverflow.com/questions/70088443/how-can-i-use-a-constraint-family-thats-in-scope-to-prove-instances-within-the。谢谢这里的回答者,我认为后续问题可以更好地解释我在这里引入的一些困惑。


TL;DR我正在努力将约束证明放入表达式中,同时在构造函数上使用具有存在约束的 GADT。 (这是一个严肃的口,对不起!)


我将问题归结为以下内容。我有一个简单的 GADT 来表示称为X和函数应用程序称为F。要点X被限制为Objects.

data GADT ix a where
  X :: Object ix a => a -> GADT ix a
  F :: (a -> b) -> GADT ix a -> GADT ix b

Constrained指的是其对象受约束的容器某物 and Object就是它某物. (edit:我真正的问题涉及Category and Cartesian课程来自受限类别 https://hackage.haskell.org/package/constrained-categories-0.4.1.0)

-- | I can constrain the values within containers of kind `* -> *`
class Constrained (ix :: * -> *) where
  type Object ix a :: Constraint

-- | Here's a trivial constraint. A more interesting one might include `Typeable a`, for ex
instance Constrained (GADT ix) where
  type Object (GADT ix) a = (Constrained ix, Object ix a)

我想写一个表达式:

-- error: Could not deduce: Object ix Int arising from a use of ‘X’
ex0 :: GADT ix String
ex0 = F show (X (3 :: Int))

虽然显而易见的解决方案有效,但在构建更大的表达式时它很快就会变得冗长:

-- Typechecks, but eventually verbose
ex1 :: Object ix Int => GADT ix String
ex1 = F show (X (3 :: Int))

我认为正确的解决方案应该是这样的:

-- error: Could not deduce: Object ix Int arising from a use of ‘X’
ex2 :: Constrained ix => GADT ix String
ex2 = F show (X (3 :: Int))

但我还是拿不到证据Object ix Int.

我确信这比我想象的要简单。我尝试过添加约束Object约束族中GADT类实例。我尝试在表达式的签名中提供约束。我努力了QuantifiedConstraints,不过,我不确定我是否完全掌握了它。请各位聪明人帮助我!


可运行:

{-# LANGUAGE GADTs #-}
{-# LANGUAGE TypeApplications #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE QuantifiedConstraints #-}
{-# LANGUAGE KindSignatures #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE TypeFamilyDependencies #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE UndecidableInstances #-}
{-# LANGUAGE AllowAmbiguousTypes #-}
{-# LANGUAGE InstanceSigs #-}

module Test where

import Data.Kind
import Data.Functor.Identity
import Data.Functor.Const

-- | I can constrain the values within containers of kind `* -> *`
class Constrained (ix :: * -> *) where
  type Object ix a :: Constraint

-- | Here's a trivial constraint. A more interesting one might include `Typeable a`, for instance
instance Constrained (GADT ix) where
  type Object (GADT ix) a = (Constrained ix, Object ix a)

-- | A demo GADT that has function application ('F'), and points ('X'). The
-- points are constrained.
data GADT ix a where
  X :: Object ix a => a -> GADT ix a
  F :: (a -> b) -> GADT ix a -> GADT ix b

-- -- Broken
-- -- error: Could not deduce: Object ix Int arising from a use of ‘X’
-- ex0 :: GADT ix String
-- ex0 = F show (X (3 :: Int))

-- Typechecks
-- but for larger programs becomes verbose, requiring many explicit constraints
ex1 :: Object ix Int => GADT ix String
ex1 = F show (X (3 :: Int))

-- -- What I want, but, it's broken
-- ex2 :: Constrained ix => GADT ix String
-- ex2 = F show (X (3 :: Int))

如果没有更多背景,很难说什么是最好的解决方案,但这里有几种可能性:

完全避免约束

就目前情况而言,您的 GADT 似乎没有太多理由进行限制X to Object。也许这只是不需要?

data GADT ix a where
  X :: a -> GADT ix a
  F :: (a -> b) -> GADT ix a -> GADT ix b

相反,约束可能来自outside当需要的时候。

咬紧牙关约束列表,但让它们变得更好

如果表达式中有许多不同的类型都需要满足相同的约束,则可以使用类似的帮助器All https://hackage.haskell.org/package/ixset-typed-0.5/docs/Data-IxSet-Typed.html#t:All

ex2' :: All (Object ix) '[Int] => GADT ix String
ex2' = F show (X (3 :: Int))

除了以下类型之外,列表中还可以有更多类型Int;和/或者您可以进行同义词约束,例如

type StdObjs ix = (Object ix Int, Object x Bool, ...)

ex2'' :: StdObjs ix => GADT ix String
ex2'' = F show (X (3 :: Int))

通过数据结构本身向后传播约束

如果您确实需要约束X值,但仍然可以在 GADT 中以另一种方式表达这一点。例如,如果函数是not一个通用函数,但已经被限制为只能接受Objects,你可以这样:

data YourFunc ix a b where
  YourFunc :: Object ix a => (a->b) -> YourFunc ix a b

show' :: Object ix Int => YourFunc ix Int String
show' = YourFunc show

这并不能直接帮助解决您所询问的问题,但也许该功能是共享的或其他什么。你甚至可以有类似的东西

class Object ix a => InferrenceChain ix a where
  type PreElem ix a :: Type
  propInferrence :: (InferrenceChain ix (PreElem a) => r) -> r

and then

data YourFunc ix a b where
  YourFunc :: InferrenceChain ix a
                 => (PreElem a -> a) -> YourFunc (PreElem a) a

那么最后你可以证明X仅仅投入的约束Object ix String在外面并递归propInferrence。但这可能会变得非常繁琐。

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

如何从范围内的约束族派生类型类实例? 的相关文章

  • 如何从 haskell 中的 IOError 获取 errno?

    我在 haskell 平台上 GHC 6 12 1 作为 apt get 安装在 Debian Squeeze 上 鉴于我需要在与最初引发它的线程不同的线程上使用它 如何从 IOError 中获取底层 errno 我需要这个的原因是因为我正
  • 为什么 Haskell 的默认字符串实现是一个字符链接列表?

    Haskell 默认值的事实String众所周知 实现在速度和内存方面都效率不高 据我所知 lists一般来说 在 Haskell 中实现为单链表 并且适用于大多数小型 简单数据类型 例如Int 这似乎不是一个好主意 但是对于String这
  • 带有泛型类声明的命名空间约束

    我想知道是否 如果可以的话如何 可以将命名空间定义为泛型类声明中的约束参数 我所拥有的是这样的 namespaceMyProject Models Entities namespaceMyProject Tests BaseTest 现在我
  • 无点镜头创建不进行类型检查

    在函数中test 我遍历一个列表 从它的成员生成镜头 然后打印一些数据 当我使用有针对性的呼叫风格时 这会起作用 当我使其成为无点时 它无法进行类型检查 为什么会出现这种情况 我该如何解决这个问题 在我看来 GHC 并没有保留排名较高的信息
  • 在依赖类型的函数式编程语言中,扁平化列表是否更容易?

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

    我才刚刚开始为你学习 Haskell 以获得伟大的好处 并且我在类型类方面遇到了一些麻烦 我想创建一个接受任何数字类型并强制其为双精度的函数 我的第一个想法是定义 numToDouble Num gt Double 但我认为这不起作用 因为
  • 使用 FoldLine 解析多个块

    对于这个简化的问题 我试图解析一个如下所示的输入 foo bar baz quux woo hoo xyzzy glulx into foo bar baz quux woo hoo xyzzy glulx 我尝试过的代码如下 import
  • Haskell 中列表列表的笛卡尔积

    给定一个长度列表的列表x所有子列表的长度都相同y 输出y x长度列表x包含每个子列表中的一项 例子 x 3 y 2 1 2 3 4 5 6 Output 2 3 8不同的输出 1 3 5 1 4 5 1 3 6 1 4 6 2 3 5 2
  • Haskell 入门

    这个问题的答案是社区努力 help privileges edit community wiki 编辑现有答案以改进这篇文章 目前不接受新的答案或互动 几天来 我一直试图理解 Haskell 中的函数式编程范例 我通过阅读教程和观看截屏视频
  • SQL 约束最小值/最大值?

    有没有办法为数字字段设置 SQL 约束 最小值应为 1234 最大值应为 4523 SQL Server 语法为the check约束 http technet microsoft com en us library ms179491 as
  • 你能识别 Haskell 程序中的无限列表吗? [复制]

    这个问题在这里已经有答案了 可能的重复 如何判断列表是否是无限的 https stackoverflow com questions 7371730 how to tell if a list is infinite 在Haskell中 你
  • 限制实体框架中子实体的数量

    底线在前 有没有一种简洁的方法可以限制可以属于实体框架中父级的子实体的数量 我现在使用的是4 3 1 问题 我正在开发一个 ASP NET MVC3 站点 它通过使用实体框架的数据访问层访问数据 我有一个 SearchList 实体 它与搜
  • 如何通过“cabal build”或“stack build”构建带有图标的项目

    我想构建一个带有图标的可执行文件 通过谷歌搜索 我发现这里的说明 https wiki haskell org Setting an executable icon 但它只能通过编译源文件来工作ghc 如果我想构建一个具有可执行文件的项目c
  • 带有 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
  • 向带有检查约束 SQL 的表添加列

    我想向表中添加一列 然后添加一个检查约束以确保其大于 0 我似乎无法让它在 oracle sl Developer 中运行 Alter TABLE store101 add column Base salary Number 7 2 con
  • 如何在Haskell中实现词法分析器和解析器

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

    我偶然发现 innoDB 约束的奇怪行为 但找不到原因 我有包含数据的表格 下面列出了它们的结构 CREATE TABLE contents id int 10 unsigned NOT NULL AUTO INCREMENT title
  • 我是否需要采取明确的操作来促进与持久数据结构的共享?

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

    我在 Haskell 中遇到 ASCII 问题 fromEnum Char gt Int toEnum Int gt Char offset Int offset fromEnum A fromEnum a toUpper Char gt

随机推荐

  • 从另一个应用程序启动时,应用程序将失去记住其堆栈的能力

    现在我已经对此进行了更多研究 我写这篇文章是为了让它更清楚 如果您正在寻找更多信息 可以在旧版本中找到一些信息 怎么了 这是指没有设置任何launchMode的应用程序 设置 因此使用默认值 您可以从市场或安装程序启动应用程序 这 启动应用
  • 将特定风格的依赖关系与维度链接起来

    我正在开发一个 Android 应用程序 它有两种类型 免费和付费 每层都有 2 个版本 轻型和重型 这是 Gradle 的实现 flavorDimensions tier distro productFlavors free dimens
  • Java 10:替换 java.xml.ws 冲突

    我必须使用java xml ws 我的项目中包含一些组件 但因为它已被弃用并且很快就会被删除 所以我想使用这些组件的替代品 所以我将此依赖项添加到我的项目中pom file
  • 如何从 Dart 的 List 中获取随机元素?

    如何从 Dart 集合中检索随机元素 var list a b c d e import dart math var list a b c d e generates a new Random object final random new
  • 为什么一个字节只有0到255?

    为什么一个字节的范围只有0到255 严格来说 术语 字节 实际上可以指具有 256 个值以外的单元 只不过是这样而已几乎普遍尺寸 从维基百科 http en wikipedia org wiki Byte 从历史上看 一个字节是 用于编码单
  • 错误 c4996 检查迭代器

    我使用 VC 2013 我有以下代码 pragma warning disable 4996 define D SCL SECURE NO WARNINGS include
  • LinqToSql 和 WCF

    在使用 WCF 服务与数据库交互的 n 层应用程序中 在整个应用程序中使用 LinqToSql 类的最佳实践方法是什么 我见过它以几种不同的方式完成 但它们似乎花费了大量时间来创建额外的接口 消息类等 这减少了您无需编写数据访问代码而获得的
  • 一次按多个键让我的角色沿对角线移动

    我遇到的问题是 当用户按下 K UP 键和 K RIGHT 键或 K UP 键和 K DOWN 键等时 我试图使我的角色在屏幕上对角移动 这是我的角色移动代码 事件处理 1 Event Handling 2 for event in pyg
  • 无法加载文件或程序集“ServiceStack”或其依赖项之一。该系统找不到指定的文件

    我试图将我的网络应用程序启动到服务器 Server Windows Server 2008 R2 企业版 IIS版本 7 5 框架版本 4 0 30319 17929 但出现以下错误 Server Error in salavirtual
  • 绑定转换器参数

    有没有办法我可以做到这一点Style
  • jQuery 克隆链接选择

    我刚刚开始 http jsfiddle net FJFFJ 1 http jsfiddle net FJFFJ 1 by 使用 JQuery 链接动态创建的下拉菜单 https stackoverflow com q 5545229 151
  • 如何开始使用 ARM 处理器?

    对于新手来说 是否建议直接从 ARM 处理器的数据表和用户手册开始 或者先了解 ARM 世界然后再继续 当我开始使用一项新的 对我来说 技术时 我首先会找到尽可能多的数据表和应用说明 然后直接阅读它们 第一个目标是快速了解该技术特有的术语
  • 打印 $_POST 变量名称和值

    我在 PHP 中有一个 POST 我并不总是知道要处理的变量字段的名称 我有一个函数可以循环遍历这些值 但是我也想捕获与之相关的变量名称 foreach POST as entry print entry br 一旦我弄清楚如何获取变量名称
  • 通过 LoadLibrary 调用 DLL 时 MFC 状态无效

    我正在与 MFC 进行斗争 并使用 LoadLibrary 动态链接 DLL 当应用程序调用DLL并且DLL在同一调用中回调时 我似乎无法正确获取MFC状态 最终 它导致了大量的断言 这是我正在做的事情的代码模型 该应用程序很正常 直接来自
  • 从 webAudio / mozAudio 获取原始 PCM 数据

    我正在尝试保存 webAudio API 的输出以供将来使用 到目前为止 我认为获取 PCM 数据并将其保存为文件将满足我的期望 我想知道 webAudio 或 mozAudio 是否已经支持保存输出流 如果不支持怎么办我从输出流获取pcm
  • Rails 3 与composed_of 模型和验证

    我有这个域模型 class Person lt ActiveRecord Base composed of address mapping w address street street w address city city w addr
  • 在 Python 3 中,是否可以为具有多个基的类动态创建元类?

    在 Python 2 中 通过一个技巧 可以创建一个具有多个基类的类 尽管基类具有以下元类 not互为子类 诀窍在于这些元类本身有一个元类 将其命名为 元元类 并且此元元类为元类提供一个调用方法 该方法可以在必要时动态创建基本元类的公共子元
  • 导入python模块时出现问题

    我正在尝试使用 pythonbitstring脚本中的模块并收到导入错误 从交互模式运行时不会发生此错误 这是代码 import bitstring b bitstring BitArray bin 001001111 当这样运行时 pyt
  • Asp.net MVC Bundle - 仅允许应用程序相对 URL (~/url)

    我在将脚本包含在bundle中时遇到以下错误 有没有办法解决这个问题 URL Scripts bootstrap js 1 0 0 1 无效 仅有的 允许使用应用程序相对 URL url 我们正在使用 CDN 因此 url 将被创建为 bo
  • 如何从范围内的约束族派生类型类实例?

    edit 我又跟进了一个具体问题 https stackoverflow com questions 70088443 how can i use a constraint family thats in scope to prove in