2020-02-20 12:43:52 +03:00
|
|
|
-- Lists.
|
|
|
|
|
-- (C) Dmitry Boulytchev, JetBrains Research, St. Petersburg State University, 2020
|
|
|
|
|
--
|
|
|
|
|
-- This unit provides a set of list-manipulation primitives.
|
|
|
|
|
|
2020-01-21 22:03:11 +03:00
|
|
|
public fun singleton (x) {
|
2020-01-20 03:38:43 +03:00
|
|
|
x : {}
|
|
|
|
|
}
|
|
|
|
|
|
2020-01-16 06:59:34 +03:00
|
|
|
public fun size (l) {
|
|
|
|
|
case l of
|
|
|
|
|
{} -> 0
|
|
|
|
|
| _ : t -> 1 + size (t)
|
|
|
|
|
esac
|
|
|
|
|
}
|
|
|
|
|
|
2020-01-15 06:12:01 +03:00
|
|
|
public fun foldl (f, acc, l) {
|
|
|
|
|
case l of
|
|
|
|
|
{} -> acc
|
|
|
|
|
| x : xs -> foldl (f, f (acc, x), xs)
|
|
|
|
|
esac
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public fun foldr (f, acc, l) {
|
|
|
|
|
case l of
|
|
|
|
|
{} -> acc
|
|
|
|
|
| x : xs -> f (foldr (f, acc, xs), x)
|
|
|
|
|
esac
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public fun iter (f, l) {
|
|
|
|
|
case l of
|
|
|
|
|
{} -> skip
|
|
|
|
|
| x : xs -> f (x); iter (f, xs)
|
|
|
|
|
esac
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public fun map (f, l) {
|
|
|
|
|
case l of
|
|
|
|
|
{} -> {}
|
|
|
|
|
| x : xs -> f (x) : map (f, xs)
|
|
|
|
|
esac
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public infix +++ at + (x, y) {
|
|
|
|
|
case x of
|
|
|
|
|
{} -> y
|
|
|
|
|
| x : xs -> x : xs +++ y
|
|
|
|
|
esac
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public fun reverse (l) {
|
|
|
|
|
fun inner (acc, l) {
|
|
|
|
|
case l of
|
|
|
|
|
{} -> acc
|
|
|
|
|
| x : xs -> inner (x : acc, xs)
|
|
|
|
|
esac
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
inner ({}, l)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public fun assoc (l, x) {
|
|
|
|
|
case l of
|
|
|
|
|
{} -> None
|
|
|
|
|
| [y, z] : ys -> if compare (x, y) == 0 then Some (z) else assoc (ys, x) fi
|
|
|
|
|
esac
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public fun find (f, l) {
|
|
|
|
|
case l of
|
|
|
|
|
{} -> None
|
|
|
|
|
| x : xs -> if f (x) then Some (x) else find (f, xs) fi
|
|
|
|
|
esac
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public fun flatten (l) {
|
2020-01-16 06:59:34 +03:00
|
|
|
local res = [0, {}], curr = [res];
|
2020-01-15 06:12:01 +03:00
|
|
|
|
|
|
|
|
fun append (x) {
|
2020-01-16 06:59:34 +03:00
|
|
|
local new = x : {};
|
2020-08-22 20:11:41 +03:00
|
|
|
|
2020-01-16 06:59:34 +03:00
|
|
|
curr [0][1] := new;
|
|
|
|
|
curr [0] := new
|
2020-01-15 06:12:01 +03:00
|
|
|
}
|
2020-08-22 20:11:41 +03:00
|
|
|
|
2020-09-23 01:39:38 +03:00
|
|
|
iter (fun (x) {iter (append, x)}, l);
|
|
|
|
|
|
|
|
|
|
res [1]
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public fun deepFlatten (l) {
|
|
|
|
|
local res = [0, {}], curr = [res];
|
|
|
|
|
|
|
|
|
|
fun append (x) {
|
|
|
|
|
local new = x : {};
|
|
|
|
|
|
|
|
|
|
curr [0][1] := new;
|
|
|
|
|
curr [0] := new
|
|
|
|
|
}
|
|
|
|
|
|
2020-08-22 20:11:41 +03:00
|
|
|
fun traverse (l) {
|
|
|
|
|
case l of
|
|
|
|
|
_ : _ -> iter (traverse, l)
|
|
|
|
|
| {} -> skip
|
|
|
|
|
| _ -> append (l)
|
|
|
|
|
esac
|
|
|
|
|
}
|
2020-02-24 01:08:09 +03:00
|
|
|
|
2020-08-22 20:11:41 +03:00
|
|
|
traverse (l);
|
2020-02-24 01:08:09 +03:00
|
|
|
|
2020-01-15 06:12:01 +03:00
|
|
|
res [1]
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public fun zip (a, b) {
|
|
|
|
|
case [a, b] of
|
|
|
|
|
[{}, {}] -> {}
|
|
|
|
|
| [a : aa, b : bb] -> [a, b] : zip (aa, bb)
|
|
|
|
|
esac
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public fun unzip (a) {
|
|
|
|
|
case a of
|
|
|
|
|
{} -> [{}, {}]
|
|
|
|
|
| [a, b] : aa ->
|
|
|
|
|
case unzip (aa) of
|
|
|
|
|
[aa, bb] -> [a : aa, b : bb]
|
|
|
|
|
esac
|
|
|
|
|
esac
|
2020-01-16 06:59:34 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public fun remove (f, l) {
|
|
|
|
|
case l of
|
|
|
|
|
{} -> {}
|
|
|
|
|
| h : t -> if f (h) then t else h : remove (f, t) fi
|
|
|
|
|
esac
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public fun filter (f, l) {
|
|
|
|
|
case l of
|
|
|
|
|
{} -> {}
|
|
|
|
|
| h : t -> if f (h) then h : filter (f, t) else filter (f, t) fi
|
|
|
|
|
esac
|
2020-01-15 06:12:01 +03:00
|
|
|
}
|