OLD | NEW |
(Empty) | |
| 1 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. |
| 4 |
| 5 import "package:expect/expect.dart"; |
| 6 |
| 7 // Dart test verifying that the parser can handle type parameterization of |
| 8 // method declarations and method invocations. Slightly adjusted version of |
| 9 // code from DEP #22. |
| 10 |
| 11 class BinaryTreeNode<K extends Comparable<K>, V> { |
| 12 final K _key; |
| 13 final V _value; |
| 14 final BinaryTreeNode<K, V> _left; |
| 15 final BinaryTreeNode<K, V> _right; |
| 16 |
| 17 BinaryTreeNode(this._key, this._value, |
| 18 {BinaryTreeNode<K, V> left: null, BinaryTreeNode<K, V> right: null}) : |
| 19 _left = left, _right = right; |
| 20 |
| 21 // Use fresh type variables. |
| 22 static BinaryTreeNode<K2, V2> insertOpt<K2, V2>(BinaryTreeNode<K2, V2> t, |
| 23 K2 key, V2 value) { |
| 24 return (t == null) ? new BinaryTreeNode(key, value) : t.insert(key, value); |
| 25 } |
| 26 |
| 27 BinaryTreeNode<K, V> insert(K key, V value) { |
| 28 int c = key.compareTo(_key); |
| 29 if (c == 0) return this; |
| 30 var _insert = (BinaryTreeNode<K, V> node, K key, V value) => |
| 31 insertOpt<K, V>(node, key, value); |
| 32 BinaryTreeNode<K, V> left = _left; |
| 33 BinaryTreeNode<K, V> right = _right; |
| 34 if (c < 0) { |
| 35 left = _insert(_left, key, value); |
| 36 } else { |
| 37 right = _insert(_right, key, value); |
| 38 } |
| 39 return new BinaryTreeNode<K, V>(_key, _value, left: left, right: right); |
| 40 } |
| 41 |
| 42 // Reuse type variables [K], [V] to test shadowing. |
| 43 static BinaryTreeNode<K, V> mapOpt<K extends Comparable<K>, V, U> |
| 44 (BinaryTreeNode<K, V> t, U f(V x)) { |
| 45 return (t == null) ? null : t.map<U>(f); |
| 46 } |
| 47 |
| 48 BinaryTreeNode<K, U> map<U>(U f(V x)){ |
| 49 var _map = (BinaryTreeNode<K, V> t, U f(V x)) => mapOpt<K, V, U>(t, f); |
| 50 return new BinaryTreeNode<K, U>( |
| 51 _key, |
| 52 f(_value), |
| 53 left: _map(_left, f), |
| 54 right: _map(_right, f)); |
| 55 } |
| 56 |
| 57 // Use fresh [K2], shadowing [V]. |
| 58 static S foldPreOpt<K2 extends Comparable<K2>, V, S>( |
| 59 BinaryTreeNode<K2, V> t, S init, S f(V t, S s)) { |
| 60 return (t == null) ? init : t.foldPre<S>(init, f); |
| 61 } |
| 62 |
| 63 S foldPre<S>(S init, S f(V t, S s)) { |
| 64 var _fold = (BinaryTreeNode<K2, V> t, S s, S f(V t, S s)) => |
| 65 foldPreOpt<K, V, S>(t, s, f); |
| 66 S s = init; |
| 67 s = f(_value, s); |
| 68 s = _fold(_left, s, f); |
| 69 s = _fold(_right, s, f); |
| 70 return s; |
| 71 } |
| 72 } |
| 73 |
| 74 class BinaryTree<K extends Comparable<K>, V> { |
| 75 final BinaryTreeNode<K, V> _root; |
| 76 |
| 77 BinaryTree._internal(this._root); |
| 78 BinaryTree.empty() : this._internal(null); |
| 79 |
| 80 BinaryTree<K, V> insert(K key, V value) { |
| 81 BinaryTree<K, V> root = BinaryTreeNode.insertOpt<K, V>(_root, key, value); |
| 82 return new BinaryTree<K, V>._internal(root); |
| 83 } |
| 84 |
| 85 BinaryTree<K, V> map<U>(U f(V x)) { |
| 86 BinaryTreeNode<K, V> root = BinaryTreeNode.mapOpt<K, V, U>(_root, f); |
| 87 return new BinaryTree<K, V>._internal(root); |
| 88 } |
| 89 |
| 90 S foldPre<S>(S init, S f(V t, S s)) { |
| 91 return BinaryTreeNode.foldPreOpt<K, V, S>(_root, init, f); |
| 92 } |
| 93 } |
| 94 |
| 95 main() { |
| 96 BinaryTree<num, String> sT = new BinaryTree<num, String>.empty(); |
| 97 |
| 98 sT = sT.insert(0, ""); |
| 99 sT = sT.insert(1, " "); |
| 100 sT = sT.insert(2, " "); |
| 101 sT = sT.insert(3, " "); |
| 102 |
| 103 BinaryTree<num, num> iT = sT.map<num>((String s) => s.length); |
| 104 |
| 105 Expect.equals(iT.foldPre<num>(0, (int i, num s) => i + s), 6); |
| 106 } |
OLD | NEW |