एमएल / (सख्त) जावा में हास्केल
यह वास्तविक वास्तविक परियोजना से है। यह लगातार अपरिवर्तनीय डेटा संरचनाओं का उपयोग करता है और आवश्यक नहीं होने पर भी पुनरावर्तन का उपयोग करता है। दरअसल, यह जावा में कोरे (परियोजना को लागू करने वाली भाषा) की तरह अधिक है, लेकिन शैली मूल रूप से एमएल के समान है। लेकिन कोरे का दर्शन यह है कि लेखक को अपने कोड को प्रारूपित नहीं करना चाहिए, इसलिए जावा कोड में से कोई भी प्रारूपित नहीं किया गया है (यह ग्रहण द्वारा स्वतःपूर्ण है)।
n तत्वों को सूची से हटाएं :
public static <T> List<T> drop(List<T> l, Integer n) {
return n == 0 ? l : drop(l.cons().tail, n - 1);
}
एमएल / हास्केल में, जहां आप सिर और पूंछ निकालने के लिए मिलान करेंगे, यहां आप कहते हैं list.cons().x
और list.cons().tail
।
सूची में एक तत्व डालें :
public static <T> List<T> insert(List<T> l, Integer i, T x) {
if (i == 0)
return cons(x, l);
return cons(l.cons().x, insert(l.cons().tail, i - 1, x));
}
सूची को शाब्दिक रूप से परिभाषित किया गया है कि बीजगणितीय डेटाटाइप को कैसे परिभाषित किया जाएगा। यहां एक ऐसा संस्करण है जिसे ग्रहण से उत्पन्न बायलरप्लेट हटाया गया है:
public final class List<T> {
public static final class Nil<T> {
}
public static final class Cons<T> {
public final T x;
public final List<T> tail;
public Cons(T x, List<T> tail) {
if (x == null)
throw new RuntimeException("null head");
if (tail == null)
throw new RuntimeException("null tail");
this.x = x;
this.tail = tail;
}
}
private final Nil<T> nil;
private final Cons<T> cons;
private List(Nil<T> nil, Cons<T> cons) {
this.nil = nil;
this.cons = cons;
}
public boolean isEmpty() {
return nil != null;
}
public Nil<T> nil() {
if (nil == null)
throw new RuntimeException("not nil");
return nil;
}
public Cons<T> cons() {
if (cons == null)
throw new RuntimeException("not cons");
return cons;
}
public static <T> List<T> cons(Cons<T> cons) {
if (cons == null)
throw new RuntimeException("constructor received null");
return new List<T>(null, cons);
}
public static <T> List<T> nil(Nil<T> nil) {
if (nil == null)
throw new RuntimeException("constructor received null");
return new List<T>(nil, null);
}
}
यहाँ एक नक्शा डेटा संरचना एक के मामले में लागू किया है trie :
public final class Map<K, V> {
private final Tree<Character, Optional<Pair<K, V>>> tree;
// keys are sorted in reverse order so entrySet can use cons instead of append
private final Comparer<Pair<Character, Tree<Character, Optional<Pair<K, V>>>>> comparer =
new PairLeftComparer<Character, Tree<Character, Optional<Pair<K, V>>>>(
new ReverseComparer<Character>(new CharacterComparer()));
private Map(Tree<Character, Optional<Pair<K, V>>> tree) {
this.tree = tree;
}
public static <K, V> Map<K, V> empty() {
return new Map<K, V>(new Tree<Character, Optional<Pair<K, V>>>(
OptionalUtils.<Pair<K, V>> nothing(),
ListUtils
.<Pair<Character, Tree<Character, Optional<Pair<K, V>>>>> nil()));
}
public Optional<V> get(K k) {
Tree<Character, Optional<Pair<K, V>>> t = tree;
for (char c : k.toString().toCharArray()) {
Tree<Character, Optional<Pair<K, V>>> t2 = getEdge(t, c);
if (t2 == null)
return nothing();
t = t2;
}
if (t.v.isNothing())
return nothing();
return some(t.v.some().x.y);
}
public Map<K, V> put(K k, V v) {
return new Map<K, V>(put(tree, k.toString(), v, k));
}
private Tree<Character, Optional<Pair<K, V>>> put(
Tree<Character, Optional<Pair<K, V>>> t, String s, V v, K k) {
if (s.equals(""))
return new Tree<Character, Optional<Pair<K, V>>>(some(Pair.pair(k, v)),
t.edges);
char c = s.charAt(0);
Tree<Character, Optional<Pair<K, V>>> t2 = getEdge(t, c);
if (t2 == null)
return new Tree<Character, Optional<Pair<K, V>>>(
t.v,
sort(
cons(
pair(
c,
put(new Tree<Character, Optional<Pair<K, V>>>(
OptionalUtils.<Pair<K, V>> nothing(),
ListUtils
.<Pair<Character, Tree<Character, Optional<Pair<K, V>>>>> nil()),
s.substring(1), v, k)), t.edges), comparer));
return new Tree<Character, Optional<Pair<K, V>>>(t.v, sort(
replace(pair(c, put(t2, s.substring(1), v, k)), t.edges), comparer));
}
private List<Pair<Character, Tree<Character, Optional<Pair<K, V>>>>> replace(
Pair<Character, Tree<Character, Optional<Pair<K, V>>>> edge,
List<Pair<Character, Tree<Character, Optional<Pair<K, V>>>>> edges) {
if (edges.cons().x.x.equals(edge.x))
return cons(edge, edges.cons().tail);
return cons(edges.cons().x, replace(edge, edges.cons().tail));
}
// I consider this O(1). There are a constant of 2^16 values of
// char. Either way it's unusual to have a large amount of
// edges since only ASCII chars are typically used.
private Tree<Character, Optional<Pair<K, V>>> getEdge(
Tree<Character, Optional<Pair<K, V>>> t, char c) {
for (Pair<Character, Tree<Character, Optional<Pair<K, V>>>> p : iter(t.edges))
if (p.x.equals(c))
return p.y;
return null;
}
public Map<K, V> delete(K k) {
return new Map<K, V>(delete(tree, k.toString()).x);
}
private Pair<Tree<Character, Optional<Pair<K, V>>>, Boolean> delete(
Tree<Character, Optional<Pair<K, V>>> t, String k) {
if (k.equals(""))
return pair(
new Tree<Character, Optional<Pair<K, V>>>(
OptionalUtils.<Pair<K, V>> nothing(), t.edges), t.edges.isEmpty());
char c = k.charAt(0);
Tree<Character, Optional<Pair<K, V>>> t2 = getEdge(t, c);
if (t2 == null)
return pair(t, false);
Pair<Tree<Character, Optional<Pair<K, V>>>, Boolean> p =
delete(t2, k.substring(1));
List<Pair<Character, Tree<Character, Optional<Pair<K, V>>>>> edges = nil();
for (Pair<Character, Tree<Character, Optional<Pair<K, V>>>> e : iter(t.edges))
if (!e.x.equals(c))
edges = cons(e, edges);
if (!p.y)
return pair(
new Tree<Character, Optional<Pair<K, V>>>(t.v, cons(pair(c, p.x),
edges)), false);
boolean oneEdge = t.edges.cons().tail.isEmpty();
return pair(new Tree<Character, Optional<Pair<K, V>>>(t.v, edges), oneEdge
&& t.v.isNothing());
}
public static class Entry<K, V> {
public Entry(K k, V v) {
this.k = k;
this.v = v;
}
public final K k;
public final V v;
}
public List<Entry<K, V>> entrySet() {
return entrySet(ListUtils.<Entry<K, V>> nil(), tree);
}
private List<Entry<K, V>> entrySet(List<Entry<K, V>> l,
Tree<Character, Optional<Pair<K, V>>> t) {
if (!t.v.isNothing()) {
Pair<K, V> p = t.v.some().x;
l = cons(new Entry<K, V>(p.x, p.y), l);
}
for (Pair<Character, Tree<Character, Optional<Pair<K, V>>>> e : iter(t.edges))
l = entrySet(l, e.y);
return l;
}
}
प्रकार कोड के रूप में ज्यादा जगह लेने लगते हैं। उदाहरण के लिए, पुट में , विधि में 302 प्रकार के अक्षर और कोड के 343 अक्षर (गिनती / स्थान नहीं) हैं।
.litcoffee
। यह मदद कर सकता है।