I want to make function maptree with standard ML

↘锁芯ラ 提交于 2019-12-23 18:23:02

问题


I want to make function maptree with standard ML. If function f(x) = x + 1; then

maptree(f, NODE(NODE(LEAF 1,LEAF 2),LEAF 3));

should make result

NODE(NODE(LEAF 2,LEAF 3),LEAF 4))

I write the code like below.

datatype 'a tree = LEAF of 'a | NODE of 'a tree * 'a tree;
fun f(x) = x + 1;
fun maptree(f, NODE(X, Y)) = NODE(maptree(f, X), maptree(f, Y))
| maptree(f, LEAF(X)) = LEAF(f X);

but when I execute this code like this

maptree(f, (NODE(NODE(LEAF 1,LEAF 2),LEAF 3)));

result is not I want to (NODE(NODE(LEAF 2,LEAF 3),LEAF 4))) but NODE(NODE(LEAF #,LEAF #),LEAF 4)). Why this happened(not a number but #)?


回答1:


# is used by the REPL when the data structure it prints is deeper than a pre-set value. If you increase that value, you'll get the result you excepted. I assume you're using SML/NJ, which calls that setting print.depth:

sml -Cprint.depth=20
- maptree(f, (NODE(NODE(LEAF 1,LEAF 2),LEAF 3)));
val it = NODE (NODE (LEAF 2,LEAF 3),LEAF 4) : int tree

You can find more options like these by executing sml -H. Look them up under the "compiler print settings" section:

compiler print settings:
     print.depth                                          (max print depth)
     print.length                                        (max print length)
     print.string-depth                            (max string print depth)
     print.intinf-depth                        (max IntInf.int print depth)
     print.loop                                                (print loop)
     print.signatures                       (max signature expansion depth)
     print.opens                                             (print `open')
     print.linewidth                   (line-width hint for pretty printer)



回答2:


Some comments:

  1. I would probably go with the definition

    datatype 'a tree = Leaf | Node of 'a tree * 'a * 'a tree
    

    so that trees with zero or two elements can also be expressed.

  2. I would probably curry the tree map function

    fun treemap f Leaf = Leaf
      | treemap f (Node (l, x, r)) = Node (treemap f l, x, treemap f r)
    

    since you can then partially apply it, e.g. like:

    (* 'abstree t' returns t where all numbers are made positive *)
    val abstree = treemap Int.abs
    
    (* 'makeFullTree n' returns a full binary tree of size n *)
    fun makeFullTree 0 = Leaf
      | makeFullTree n =
        let val subtree = makeFullTree (n-1)
        in Node (subtree, n, subtree)
        end
    
    (* 'treetree t' makes an int tree into a tree of full trees! *)
    val treetree = treemap makeFullTree
    
  3. You may at some point want to fold a tree, too.



来源:https://stackoverflow.com/questions/36986057/i-want-to-make-function-maptree-with-standard-ml

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!