和与异质和之间的一般同构

2023-12-19

是否有 Haskell 库提供(或协助编写)总和类型与关联的异构总和类型之间的通用同构?

采用以下总和类型,

data TR = TR_Index | TR_Inner R

现在我们将它与异质和联系起来NS I xs https://hackage.haskell.org/package/sop-core-0.5.0.2/docs/Data-SOP.html#t:NS(其中“xs”由类型类定义;请参阅MotleyRouteSubRoutes以下)。然后定义一个同构来来回转换:

instance MotleyRoute TR where
  -- `SingletonRoute s` is isomorphic to `()`
  -- `PrefixedRoute s r` is isomorphic to `Const r s`
  type MotleyRouteSubRoutes TR = 
    '[ SingletonRoute "index.html"
     , PrefixedRoute "inner" R
     ]
  motleyRouteIso =
    iso
      ( \case
          TR_Index -> Z $ I SingletonRoute
          TR_Inner r -> S $ Z $ I $ PrefixedRoute r
      )
      ( \case
          Z (I SingletonRoute) -> TR_Index
          S (Z (I (PrefixedRoute r))) -> TR_Inner r
          S (S x) -> case x of {}
      )

我的目标是写motleyRouteIso一般地(以及定义MotleyRouteSubRoutes一般而言,但这可能超出了此处的范围)。我打算从头开始使用generics-sop,但我想知道是否已经有一个图书馆可以为我做到这一点。generic-optics提供了一个IsList https://hackage.haskell.org/package/generic-optics-2.2.1.0/docs/Data-Generics-Product-HList.html但这适用于乘积而不是总和。

(有关完整上下文,请参阅this PR https://github.com/srid/ema/pull/93)


到目前为止还没有看到任何答案,我假设目前不存在这样的预构建解决方案。所以这是我基于的方法generics-sop.

RGeneric

首先我添加了一个RGenerictype-class 来缩小路由 ADT 的构造函数只能包含 0 或 1 个产品的情况:

-- | Like `Generic` but for Route types only.
class RGeneric r where
  type RCode r :: [Type]
  rfrom :: r -> NS I (RCode r)
  rto :: NS I (RCode r) -> r

这个实例的实现相当简单,使用generics-sop。你可以在这里看到它 https://github.com/srid/ema/pull/93/commits/9b9ca3712cda6051fcfa493c307838e5edc89882 (the RouteNP约束捕获了我们感兴趣的路线类型的预期“形状”)。

介绍Coercible用于举重

请注意,各个类型MotleyRouteSubRoutes或多或少可以强制路由类型构造函数。因此,我利用这些知识从方程中“消除”了特定类型,从而向通用实现迈出了一大步。具体来说:

@@ -95,12 +95,12 @@ instance MotleyRoute TR where
   motleyRouteIso =
     iso
       ( \case
-          TR_Index -> Z $ I SingletonRoute
-          TR_Inner r -> S $ Z $ I $ PrefixedRoute r
+          TR_Index -> Z $ coerce ()
+          TR_Inner r -> S $ Z $ coerce r
       )
       ( \case
-          Z (I SingletonRoute) -> TR_Index
-          S (Z (I (PrefixedRoute r))) -> TR_Inner r
+          Z (I (coerce -> ())) -> TR_Index
+          S (Z r) -> TR_Inner $ coerce r
           S (S x) -> case x of {}
       )

请注意,在新版本中没有引用SingletonRoute or PrefixedRoute.

完整差异在这里 https://github.com/srid/ema/pull/93/commits/f9c7908bf8b0a622b18ea34eea41b258d55596ff.

通用ISO

有了这个地方,现在可以非常简单地通用实施motleyRouteIso using trans_NS https://hackage.haskell.org/package/sop-core-0.5.0.2/docs/Data-SOP-NS.html#v:trans_NS因为Coercible约束为我们完成了所有繁重的工作,RGeneric抽象出处理路线类型的预期“形状”。它看起来像这样:

-- Rough code (leaving out the constraints)
gmotleyRouteIso =
  iso (gtoMotley @r . rfrom) (rto . gfromMotley @r)
  where 
     gtoMotley = trans_NS (Proxy @Coercible) coerce
     gfromMotley = trans_NS (Proxy @Coercible) coerce

The 改变就在这里 https://github.com/srid/ema/pull/93/commits/e458f6228c00a9b32ac92119f4e47c673e2ef04f.

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

和与异质和之间的一般同构 的相关文章

  • 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
  • 这个记忆的斐波那契函数是如何工作的?

    在我正在做的函数式编程课程的当前练习作业中 我们必须制作给定函数的记忆版本 为了解释记忆化 给出以下示例 fiblist fibm x x lt 0 fibm 0 0 fibm 1 1 fibm n fiblist n 1 fiblist
  • Haskell scala 互操作性

    我是 Scala 初学者 来自面向对象范式 在了解 Scala 的函数式编程部分时 我被引导到 Haskell 纯函数式编程语言 探索 SO 问题答案 我发现 Java Haskell 具有互操作性 我很想知道 Scala Haskell
  • 我应该在 Turtle 或 Foldl 包中使用折叠吗?

    我在使用 Turtle 时遇到了一些困难 直到盯着难以理解的错误消息几分钟后才意识到我使用了错误的fold功能 https hackage haskell org package turtle 1 5 8 docs Turtle Shell
  • 将 num 的签名键入 double?

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

    我正在阅读以下内容 https en wikibooks org wiki Haskell Graph reduction https en wikibooks org wiki Haskell Graph reduction 其内容如下
  • 使用 FoldLine 解析多个块

    对于这个简化的问题 我试图解析一个如下所示的输入 foo bar baz quux woo hoo xyzzy glulx into foo bar baz quux woo hoo xyzzy glulx 我尝试过的代码如下 import
  • 如何在 Haskell 中漂亮地打印表格?

    我想在 Haskell 中漂亮地打印一个类似表格的数据结构 列列表 例如 Table StrCol strings a bc c IntCol ints 1 30 2 DblCol doubles 2 0 4 5 3 2 应该渲染类似 st
  • 简单 Haskell Monad - 随机数

    我正在尝试扩展代码这个帖子 https stackoverflow com questions 3944170 haskell and state 接受的答案 允许我能够基于以种子作为参数的函数 randomGen 调用 randomGen
  • Haskell Stack 从 github 安装包依赖项

    是否可以使用 Haskell 堆栈从 github 安装软件包的版本 例如在一个 cabal or a stack yaml文件 如何在 git repo branch revision 上指向依赖项 对于堆栈 The 的文档stack y
  • 如何在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
  • 为什么 ZipList 不是 List 的默认应用实例

    我目前正在学习 Haskell 中的应用程序 如果我没记错的话 列表有两个不同的应用实例 List and ZipList 第二个被定义为包装列表值的新类型 这ZipList应用实例对我来说似乎更直观 这可能是一个愚蠢的问题 但有具体原因吗
  • Haskell 对于 Web 应用程序来说足够成熟吗? [关闭]

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

    我正在尝试在 Haskell 中尝试 System F 类型 并通过以下方式实现了自然数的 Church 编码type 当加载这段代码时 OPTIONS GHC Wall LANGUAGE RankNTypes type CNat fora
  • 类型级别集结合律的证明

    我试图证明类型级函数Union https hackage haskell org package type level sets 0 8 5 0 docs Data Type Set html t Union是关联的 但我不确定应该如何完
  • 约束包如何工作?

    背后的想法数据 约束 Forall http hackage haskell org packages archive constraints 0 3 2 doc html src Data Constraint Forall html据我
  • 如何在haskell中用另一个字符串替换一个字符串

    我想用不同的字符串替换输入文件中的字符串 我正在寻找一种方法 但似乎我只能逐个字符地更改字符串 例如在我下面的代码中 replace String gt String replace replace x xs if x then y rep
  • Parsec.Expr 具有不同优先级的重复前缀

    Parsec Expr buildExpressionParser 的文档说 相同优先级的前缀和后缀运算符只能出现一次 即 如果 为前缀否定 则不允许使用 2 但是 我想解析这样的字符串 具体来说 考虑以下语法 sentence ident
  • 在 ghci 下执行 `(read "[Red]") :: [Color]` 时会发生什么?

    我正在阅读以下小节现实世界 Haskell 第 6 章 类型类 http book realworldhaskell org read using typeclasses html关于一个实例Read for Color 它实现了reads

随机推荐