// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file // for details. All rights reserved. Use of this source code is governed by a // BSD-style license that can be found in the LICENSE file. /// Dart test verifying that the parser can handle type parameterization of /// method declarations and method invocations. Slightly adjusted version of /// code from DEP #22. library generic_methods_test; import "package:expect/expect.dart"; class BinaryTreeNode, V> { final K _key; final V _value; final BinaryTreeNode? _left; final BinaryTreeNode? _right; BinaryTreeNode(this._key, this._value, {BinaryTreeNode? left: null, BinaryTreeNode? right: null}) : _left = left, _right = right; // Use fresh type variables. static BinaryTreeNode insertOpt, V2>( BinaryTreeNode? t, K2 key, V2 value) { return (t == null) ? new BinaryTreeNode(key, value) : t.insert(key, value); } BinaryTreeNode insert(K key, V value) { int c = key.compareTo(_key); if (c == 0) return this; var _insert = (BinaryTreeNode? node, K key, V value) => insertOpt(node, key, value); BinaryTreeNode? left = _left; BinaryTreeNode? right = _right; if (c < 0) { left = _insert(_left, key, value); } else { right = _insert(_right, key, value); } return new BinaryTreeNode(_key, _value, left: left, right: right); } // Reuse type variables [K], [V] to test shadowing. static BinaryTreeNode? mapOpt, V, U>( BinaryTreeNode? t, U f(V x)) { return (t == null) ? null : t.map(f); } BinaryTreeNode map(U f(V x)) { var _map = (BinaryTreeNode? t, U f(V x)) => mapOpt(t, f); return new BinaryTreeNode(_key, f(_value), left: _map(_left, f), right: _map(_right, f)); } // Use fresh [K2], shadowing [V]. static S foldPreOpt, V, S>( BinaryTreeNode? t, S init, S f(V t, S s)) { return (t == null) ? init : t.foldPre(init, f); } S foldPre(S init, S f(V t, S s)) { var _fold = (BinaryTreeNode? t, S s, S f(V t, S s)) => foldPreOpt(t, s, f); S s = init; s = f(_value, s); s = _fold(_left, s, f); s = _fold(_right, s, f); return s; } } class BinaryTree, V> { final BinaryTreeNode? _root; BinaryTree._internal(this._root); BinaryTree.empty() : this._internal(null); BinaryTree insert(K key, V value) { BinaryTreeNode root = BinaryTreeNode.insertOpt(_root, key, value); return new BinaryTree._internal(root); } BinaryTree map(U f(V x)) { BinaryTreeNode? root = BinaryTreeNode.mapOpt(_root, f); return new BinaryTree._internal(root); } S foldPre(S init, S f(V t, S s)) { return BinaryTreeNode.foldPreOpt(_root, init, f); } } main() { BinaryTree sT = new BinaryTree.empty(); sT = sT.insert(0, ""); sT = sT.insert(1, " "); sT = sT.insert(2, " "); sT = sT.insert(3, " "); BinaryTree iT = sT.map((String s) => s.length); Expect.equals(iT.foldPre(0, (num i, num s) => i + s), 6); }