微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

在折叠树的 Typed Racket 中转换为任意类型

如何解决在折叠树的 Typed Racket 中转换为任意类型

我正在尝试生成一个类型化的 Racket 过程,对于某些类型 A,采用 Tree,以及从两个 AA函数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

我的代码

(: 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 类型的定义,就很难回答这个问题。但是一般的答案不是强制转换,而是具有一种类型,它是某种类型的 节点的树。我不了解 Racket 中的类,最不了解它们与类型化 Racket 的所有交互(这似乎都可能会发生变化),但这里是如何使用 struct球拍:

(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-valuetree-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(map (λ (child) ...) (tree-children tree)) 并且它知道 {{ 1}} 确实如此。所以我不得不告诉它(旧版本有问题,使用 (Treeof A) 而不是 tree,这隐藏了这个问题。

,

使用结构类型定义如 the answer 中的 tfb

#lang typed/racket

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

以下定义有效(有点):

(: fold-tree (All (A R) (-> (Treeof A) (-> A R R) R R)))
(define (fold-tree tree f base)
  (f (tree-value tree)
     (foldr
          (lambda ((child : (Treeof A)) (r : R))
            (fold-tree child f r))
          base
          (tree-children tree))))

现在在交互窗口中尝试,

(fold-tree (tree 1 (list (tree 2 '()))) + 0)

工作和回报

- : Integer [more precisely: Nonnegative-Integer]
3

但尝试看似等效的

(fold-tree (tree 1 (list (tree 2 '()))) (lambda (a r) (+ a r)) 0)

出现很多错误。

更新:感谢 tfb 的输入,以下调用所有工作:

> (fold-tree (tree 1 (list (tree 2 '()))) (lambda ((a : Number) (r : Number)) (+ a r)) 0)
- : Number
3

> (fold-tree (tree 1 (list (tree 2 '()))) (lambda ((a : Any) (b : Any)) (cons a b)) 0)
- : (U Zero (Pairof Any Any))
'(1 2 . 0)

> (fold-tree (tree 1 (list (tree 2 '()))) (lambda ((a : Any) (b : Any)) (cons a b)) '())
- : (U Null (Pairof Any Any))
'(1 2)

> (fold-tree (tree 1 (list (tree 2 '()))) (lambda ((a : Any) (b : (Listof Any)))
     (cons a b)) '())
- : (Listof Any)
'(1 2)

> (fold-tree (tree 1 (list (tree 2 '()))) (lambda ((a : Number) (b : (Listof Number))) 
     (cons a b)) '())
- : (Listof Number)
'(1 2)

> (fold-tree (tree 1 (list (tree 2 '()))) (lambda (a b) (cons a b)) '())
- : (U Null (Pairof Any Any))
'(1 2)

> (fold-tree (tree 1 (list (tree 2 '()))) cons '())
*** Type Checker: Polymorphic function `fold-tree' could not be applied to arguments:
Argument 1:
  Expected: (Treeof A)
  Given:    (Treeof Positive-Byte)
Argument 2:
  Expected: (-> A R R)
  Given:    (All (a b) (case-> (-> a (Listof a) (Listof a)) (-> a b (Pairof a b))))
Argument 3:
  Expected: R
  Given:    Null
 in: (fold-tree (tree 1 (list (tree 2 (quote ())))) cons (quote ()))
> 

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。