a02d5bb211
Change-Id: I7dafd578cf8da38616ae25e5ce8dbbc7e3213014 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/425185 Reviewed-by: Lasse Nielsen <lrn@google.com> Commit-Queue: Lasse Nielsen <lrn@google.com> Auto-Submit: Bob Nystrom <rnystrom@google.com>
126 lines
3.4 KiB
Dart
126 lines
3.4 KiB
Dart
// 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<K extends Comparable<K>, V> {
|
|
final K _key;
|
|
final V _value;
|
|
final BinaryTreeNode<K, V>? _left;
|
|
final BinaryTreeNode<K, V>? _right;
|
|
|
|
BinaryTreeNode(
|
|
this._key,
|
|
this._value, {
|
|
BinaryTreeNode<K, V>? left = null,
|
|
BinaryTreeNode<K, V>? right = null,
|
|
}) : _left = left,
|
|
_right = right;
|
|
|
|
// Use fresh type variables.
|
|
static BinaryTreeNode<K2, V2> insertOpt<K2 extends Comparable<K2>, V2>(
|
|
BinaryTreeNode<K2, V2>? t,
|
|
K2 key,
|
|
V2 value,
|
|
) {
|
|
return (t == null) ? new BinaryTreeNode(key, value) : t.insert(key, value);
|
|
}
|
|
|
|
BinaryTreeNode<K, V> insert(K key, V value) {
|
|
int c = key.compareTo(_key);
|
|
if (c == 0) return this;
|
|
var _insert = (BinaryTreeNode<K, V>? node, K key, V value) =>
|
|
insertOpt<K, V>(node, key, value);
|
|
BinaryTreeNode<K, V>? left = _left;
|
|
BinaryTreeNode<K, V>? right = _right;
|
|
if (c < 0) {
|
|
left = _insert(_left, key, value);
|
|
} else {
|
|
right = _insert(_right, key, value);
|
|
}
|
|
return new BinaryTreeNode<K, V>(_key, _value, left: left, right: right);
|
|
}
|
|
|
|
// Reuse type variables [K], [V] to test shadowing.
|
|
static BinaryTreeNode<K, U>? mapOpt<K extends Comparable<K>, V, U>(
|
|
BinaryTreeNode<K, V>? t,
|
|
U f(V x),
|
|
) {
|
|
return (t == null) ? null : t.map<U>(f);
|
|
}
|
|
|
|
BinaryTreeNode<K, U> map<U>(U f(V x)) {
|
|
var _map = (BinaryTreeNode<K, V>? t, U f(V x)) => mapOpt<K, V, U>(t, f);
|
|
return new BinaryTreeNode<K, U>(
|
|
_key,
|
|
f(_value),
|
|
left: _map(_left, f),
|
|
right: _map(_right, f),
|
|
);
|
|
}
|
|
|
|
// Use fresh [K2], shadowing [V].
|
|
static S foldPreOpt<K2 extends Comparable<K2>, V, S>(
|
|
BinaryTreeNode<K2, V>? t,
|
|
S init,
|
|
S f(V t, S s),
|
|
) {
|
|
return (t == null) ? init : t.foldPre<S>(init, f);
|
|
}
|
|
|
|
S foldPre<S>(S init, S f(V t, S s)) {
|
|
var _fold = (BinaryTreeNode<K, V>? t, S s, S f(V t, S s)) =>
|
|
foldPreOpt<K, V, S>(t, s, f);
|
|
S s = init;
|
|
s = f(_value, s);
|
|
s = _fold(_left, s, f);
|
|
s = _fold(_right, s, f);
|
|
return s;
|
|
}
|
|
}
|
|
|
|
class BinaryTree<K extends Comparable<K>, V> {
|
|
final BinaryTreeNode<K, V>? _root;
|
|
|
|
BinaryTree._internal(this._root);
|
|
BinaryTree.empty() : this._internal(null);
|
|
|
|
BinaryTree<K, V> insert(K key, V value) {
|
|
BinaryTreeNode<K, V> root = BinaryTreeNode.insertOpt<K, V>(
|
|
_root,
|
|
key,
|
|
value,
|
|
);
|
|
return new BinaryTree<K, V>._internal(root);
|
|
}
|
|
|
|
BinaryTree<K, U> map<U>(U f(V x)) {
|
|
BinaryTreeNode<K, U>? root = BinaryTreeNode.mapOpt<K, V, U>(_root, f);
|
|
return new BinaryTree<K, U>._internal(root);
|
|
}
|
|
|
|
S foldPre<S>(S init, S f(V t, S s)) {
|
|
return BinaryTreeNode.foldPreOpt<K, V, S>(_root, init, f);
|
|
}
|
|
}
|
|
|
|
main() {
|
|
BinaryTree<num, String> sT = new BinaryTree<num, String>.empty();
|
|
|
|
sT = sT.insert(0, "");
|
|
sT = sT.insert(1, " ");
|
|
sT = sT.insert(2, " ");
|
|
sT = sT.insert(3, " ");
|
|
|
|
BinaryTree<num, num> iT = sT.map<num>((String s) => s.length);
|
|
|
|
Expect.equals(iT.foldPre<num>(0, (num i, num s) => i + s), 6);
|
|
}
|