首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >树元积SMLNJ

树元积SMLNJ
EN

Stack Overflow用户
提问于 2017-09-21 00:25:27
回答 2查看 210关注 0票数 1

我有以下qtree数据类型:

代码语言:javascript
复制
datatype 'a qtree = Leaf of 'a
|   Node of 'a branches
and 'a branches = Empty
|   Branch of 'a qtree * 'a branches

示例树的定义如下:

代码语言:javascript
复制
val tr1 = 
Node(Branch(Leaf(2),
    Branch(Node(Branch(Leaf(6),
    Branch(Leaf(5),Empty))),
Branch(Node(Empty),Empty))))

下面是tr1的可视化表示

代码语言:javascript
复制
  /|\
 / | \
2 / \
 /   \
6     5

我定义了以下函数tree_prod来查找qtree中值的乘积

代码语言:javascript
复制
fun tree_prod(Leaf(n)) = n
|   tree_prod(Empty) = 1
|   tree_prod(Node(br)) = tree_prod(br)
|   tree_prod(Branch(n, br)) = tree_prod(n) * tree_prod(br)

但是我收到以下错误,这些错误似乎是由于qtreebranches之间的类型混淆而发生的。

代码语言:javascript
复制
stdIn:10.5-13.42 Error: parameter or result constraints of clauses don't 
agree [tycon mismatch]
  this clause:      'Z branches -> 'Y
  previous clauses:      'X qtree -> 'Y
  in declaration:
    tree_prod =
      (fn Leaf n => n
         | Empty => 1
         | Node br => tree_prod br
         | Branch (<pat>,<pat>) => tree_prod <exp> * tree_prod <exp>)
stdIn:10.5-13.42 Error: parameter or result constraints of clauses don't 
agree [tycon mismatch]
  this clause:      'Z branches -> 'Y
  previous clauses:      'X qtree -> 'Y
  in declaration:
    tree_prod =
      (fn Leaf n => n
        | Empty => 1
        | Node br => tree_prod br
        | Branch (<pat>,<pat>) => tree_prod <exp> * tree_prod <exp>)
stdIn:12.19-12.27 Error: operator and operand don't agree [tycon mismatch]
  operator domain: [int ty] qtree
  operand:         [int ty] branches
  in expression:
    tree_prod br
stdIn:13.24-13.42 Error: operator and operand don't agree [tycon mismatch]
  operator domain: [int ty] qtree
  operand:         [int ty] branches
  in expression:
    tree_prod br

如何纠正这些错误?

奖励:如何使用折叠实现此功能?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2017-09-21 05:45:14

我自己找出了答案。通过将其划分为两个独立的函数,我能够指定我想要使用的类型。

以下是工作解决方案:

代码语言:javascript
复制
fun tree_prod (Leaf(n)) = n
|   tree_prod (Node(br)) = branches_prod(br)
and branches_prod (Empty) = 1
|   branches_prod (Branch(n, br)) =
    tree_prod(n) * branches_prod(br)
票数 2
EN

Stack Overflow用户

发布于 2017-09-21 11:20:19

您的tree_prod试图应用于这两种类型,这是行不通的-您需要两个函数。

如果您可以更改类型,则可以使用以下事实:'a branches'a qtree的列表同构( EmptynilBranchcons)。

代码语言:javascript
复制
datatype 'a qtree = Leaf of 'a
                  | Node of ('a qtree) list

然后你可以折叠在树枝上:

代码语言:javascript
复制
fun tree_prod (Leaf n) = n
  | tree_prod (Node br) = List.foldl (fn (tree, acc) => tree_prod tree * acc) 1 br

val tr1 = Node [Leaf 2, Node [Leaf 6, Leaf 5], Node []]
- tree_prod tr1;
val it = 60 : int

如果不想更改类型,可以在'a branches上编写自己的折叠,与列表折叠的格式相同。

像这样的东西可能会起作用:

代码语言:javascript
复制
fun branch_fold f x Empty = x
  | branch_fold f x (Branch t bs) = branch_fold f (f (t, x)) bs

并且会给出一个几乎相同的“产品”:

代码语言:javascript
复制
fun tree_prod (Leaf n) = n
  | tree_prod (Node br) = branch_fold (fn (tree, acc) => tree_prod tree * acc) 1 br
票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/46333583

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档