在折叠树的 Typed Racket 中投射到任意类型

2024-01-20

我正在尝试为某些类型生成一个类型化的球拍程序A,需要一个Tree,以及两个函数As to an A,另一个类型的参数A,并返回一个类型的值A。我不太熟悉(All)语法,但我尝试使用它。不幸的是,我的代码在构建时产生以下错误消息:

Type Checker: Polymorphic function `foldr' could not be applied to arguments:
Types: (-> a b b) b (Listof a)  -> b
       (-> a b c c) c (Listof a) (Listof b)  -> c
       (-> a b c d d) d (Listof a) (Listof b) (Listof c)  -> d
Arguments: (-> A A A) A (Listof Any)
Expected result: A

My code:

(: fold : (All (A) (Instance Tree) (A A -> A) A -> A))
(define (fold tree f base)
  (foldr
    f
    base
    (cons
      (value tree)
      (map 
        (lambda
          ([tree : (Instance Tree)])
          (fold tree f base)
          ) 
        (children tree)
        )
      )
    )
  )

我尝试简化该功能,直到它开始工作,这就是它开始工作的地方:

(: fold : (All (A) (Instance Tree) (A A -> A) A -> A))
(define (fold tree f base)
  (foldr f base (list base))
)

我认为发生的情况是类型检查器不知道这一点(value tree)也是类型A。有什么办法我可以(Cast)它是一种类型A?如果没有,我将如何使其发挥作用?


如果没有定义Tree打字这个问题很难回答。但一般来说,答案不是强制转换,而是拥有一个树类型of某种类型的节点。我不了解 Racket 中的类,尤其不了解它们与类型化 Racket 的交互(这似乎都可能发生变化),但以下是您如何做到这一点structs,在类型化的 Racket 中得到了很好的支持:

(struct (A) tree
  ((value : A)
   (children : (Listof (Treeof A))))
  #:type-name Treeof)

现在我可以检查一下:

> (tree 1 (list (tree -1 '())))
- : (Treeof (U Negative-Fixnum One))
#<tree>
> (tree 1 (list (tree 'x '())))
- : (Treeof (U 'x One))
#<tree>

好吧,它计算出的类型有点无用,但它们是正确的。

一旦你完成了这个,它就会知道一些美好的事情tree-value and tree-children:

> tree-value
- : (All (A) (-> (Treeof A) A))
#<procedure:tree-value>
> tree-children
- : (All (A) (-> (Treeof A) (Listof (Treeof A))))
#<procedure:tree-children>

这足以编写您的函数(我不确定它是否正确,但它的类型现在有意义):

(: fold-tree (All (A) (-> (Treeof A) (-> A A A) A A)))
(define (fold-tree tree f base)
  (foldr f base
         (cons
          (tree-value tree)
          ;; I don't know why it needs this since it knows about tree-children
          (map (λ ((child : (Treeof A)))
                 (fold-tree child f base))
               (tree-children tree)))))

请注意,由于某种原因,它无法解决这个问题child in (map (λ (child) ...) (tree-children tree)) is a (Treeof A)尽管它知道tree是并且它知道什么tree-children做。所以我不得不告诉它(旧版本有缺陷并使用tree代替child,掩盖了这个问题。

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

在折叠树的 Typed Racket 中投射到任意类型 的相关文章

  • B 树和 2-3-4 树之间的区别

    B 树和 2 3 4 树有什么区别 另外 你如何找到每个的最大和最小高度 链接到维基百科 http en wikipedia org wiki 2 3 4 tree and引用 2 3 4 树是 4 阶 B 树 A 2 3 4 is a B
  • 最大函数c树高度

    c 中是否有 max 函数 所以我可以做这样的事情来计算树高 或者也许有更好的方法来计算树高 int height struct node tree if tree NULL return 0 return 1 max height tre
  • 构建具有继承的通用树

    我正在构建一个通用的Tree
  • 如何在 Clojure 中遍历一棵树,同时收集每个节点节点的值?

    我想创建一个函数来收集二叉树中每个节点的值 在 ClojureDocs 中 我发现了几个用于遍历树 图的函数 例如 tree seq prewalk 和 postwalk https clojuredocs org clojure core
  • Python 中的树形图

    我想用 Python 绘制树 决策树 组织结构图等 有哪些库可以帮助我完成这些任务 I develop ETE http etetoolkit org which is a python package intended among oth
  • 基本树概念:定义祖先

    祖先的定义是什么 更具体地说 E 会是 H 的祖先吗 或者更简单地说 F C A 是 H 的祖先 也许甚至是G 我只是想澄清这个简单的概念 E 不是 H 的祖先 它是uncle因为它是一个siblingF 的parent of H F C
  • 创建二叉树的时间复杂度

    我正在尝试从提供的源创建一棵树 要添加到树中的 2 个节点 以及应添加这 2 个新闻节点的节点 为了找到该节点在树中的位置 我使用了中序遍历 该遍历的时间复杂度为 O n 因此 如果要在树中添加 n 个节点 则创建整个树的时间复杂度为 O
  • C 有没有做字符串加法的工具?

    我正在创建一个函数 该函数返回函数的导数 该函数表示为树形结构 x 5 3 14 x 具有以下形式的节点 typedef struct node char fx function struct node gx left hand side
  • 重新创建一棵扁平的树

    我有一个地图向量 我想以嵌套方式对其进行转换 数据结构如下 def data id 1 name a parent 0 id 2 name b parent 0 id 3 name c parent 0 id 4 name a 1 pare
  • 什么是“3D语法”?

    在编写 Racket 宏的上下文中 3D 语法 是什么意思 这句话我听过好几次了 包含一次对宏的引用I正在写作 但那是不久前的事了 我修复了它 现在我不记得我最初做错了什么 另外 是 3D 语法吗always坏的 或者是像eval 如果你认
  • 如何在方案中向后打印字符串?

    我知道如果我按照以下方式编写方案代码并输入 单词 a b c 它将以相同的顺序输出列表 您能告诉我是否有一种方法可以以相反的顺序打印出来 例如 列出 c b a 它需要是我以相反顺序打印出来的用户输入 所以 我不能称之为 反向 a b c
  • Beaglebone Black 上的 GPIO

    我目前遇到了 Beaglebone black GPIO 引脚的问题 我正在寻找一种正确的方法来读取 C 中的 GPIO 引脚 p8 4 的值 如果我理解正确的话 我尝试使用一个库 该库使用了在引入设备树之前不支持的旧方法 我尝试寻找其他解
  • Tic-Tac-Toe AI:如何制作树?

    在制作井字游戏机器人时 我在尝试理解 树 时遇到了巨大的障碍 我理解这个概念 但我不知道如何实现它们 有人可以向我展示一个如何为这种情况生成树的示例吗 或者关于生成树的好教程 我想最困难的部分是生成部分树 我知道如何实现生成整棵树 但不知道
  • 使用霍夫曼代码压缩文件的步骤

    我知道有很多涉及霍夫曼代码的问题 包括我自己的另一个问题 但我想知道实际编码文本文件的最佳方法是什么 减压看似微不足道 遍历树 在 0 处向左 在 1 处向右 打印字符 但是 如何进行压缩呢 以某种方式将字符的位表示存储在树的节点中 每次遇
  • Foldl 是否比其严格的表亲 Foldl' 更好?

    Haskell 有两个列表左折叠函数 foldl 以及 严格 版本 foldl 不严格的问题foldl是它建造了一座重击塔 foldl 0 1 5 gt 0 1 2 3 4 5 gt 15 这会浪费内存 并且如果列表中的项太多 可能会导致堆
  • 为什么这个 Clojure 减速器 r/fold 没有提供任何性能优势?

    我想知道为什么下面的代码在 r fold 的情况下没有提供加速 我对减速器有什么误解吗 我在一个相当慢的 尽管有 2 个核心 Ubuntu 12 04 开发盒上运行它 通过 emacs 和 lein 运行 每个都有相同的结果 require
  • 从 XML 构建树结构的速度很慢

    我正在将 XML 文档解析为我自己的结构 但对于大型输入来说构建它非常慢 是否有更好的方法来做到这一点 public static DomTree
  • 非二叉树的中序树遍历

    对于比二叉树更宽的树 术语 中序遍历 是否有明确定义的含义 或者 前 和 后 顺序是唯一有意义的 DFS 类型吗 我的意思是与n每个节点 gt 2 个子节点 我猜是为了n这甚至可能意味着之后要转到 根 n 2孩子们 但这曾经这样使用过吗 那
  • 使用 Java 进行树可视化 [关闭]

    Closed 此问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 我正在寻找一个库来生成图形或树 例如组织图表 该库应该能够从该图中生成纯图像 有谁知道一个好的 希望开源
  • 应用对数来导航树

    我曾经知道一种使用对数从树的一片叶子移动到树的下一个 有序 叶子的方法 我认为它涉及获取 当前 叶子的位置值 排名 并将其用作从根向下到新目标叶子的新遍历的种子 一直使用对数函数测试来确定是否沿着右或左节点向下到达叶子 我已经不记得如何运用

随机推荐