Skip to content

Instantly share code, notes, and snippets.

@kurisuwhyte
Created August 20, 2013 15:04
Show Gist options
  • Save kurisuwhyte/6282598 to your computer and use it in GitHub Desktop.
Save kurisuwhyte/6282598 to your computer and use it in GitHub Desktop.
Representing HTML as first-class entities in Dart
// This is a really bad implementation of a simple algebraic data type in Dart please don't kill meee~
class None implements Option<None> {
map(f) => this;
operator >= (f) => this;
operator | (x) => x;
None();
}
class Option<T> {
final value;
static final _none = new None();
Option<T> map(T f(T)) => new Option(f(value));
Option<T> operator >= (Option<T> f(T)) => f(value);
Option<T> operator | (Option<T> x) => this;
Option(this.value);
factory Option.none() => _none;
}
abstract class Html<A> {
String toString();
Option<A> parent;
}
class Element<A, B> extends Html<B> {
final String tag;
List<A> children;
toString() => "<$tag>${children.map((c) => c.toString()).join('')}</$tag>";
}
// You'd need to use a different approach to encode the hierarchy here because
// as far as I know, Dart doesn't support union types.
class Text extends Html<Element> {
final String text;
Option<Element> parent = new Option.none();
toString() => text;
Text(this.text);
}
class ListItem extends Element<Text, Element> {
final tag = "li";
ListItem(String x) => this.children = [x];
}
class List extends Element<ListItem, Element> {
final tag = "ul";
List<ListItem> children;
List(this.children);
}
// Using
class TodoList {
final List<String> items;
toString() => new List(items.map((a) => new ListItem(new Text(a)))).toString();
TodoList(this.items);
}
main() {
var x = new TodoList([ "First thing", "Second thing", "Third thing" ]);
print(x.toString());
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment