Created
September 14, 2012 09:43
-
-
Save kos59125/3721051 to your computer and use it in GitHub Desktop.
Purely Functional Random Access List in F# (Okasaki 1995)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
module RandomAccessList | |
open System | |
let indexOutOfBounds = ArgumentOutOfRangeException ("index") | |
let emptyList = ArgumentException ("Empty list") | |
type Tree<'a> = | |
| Leaf of 'a | |
| Node of 'a * 'a Tree * 'a Tree | |
type tree<'a> = Tree<'a> | |
module Tree = | |
let rec lookup = function | |
| _, Leaf x, 0 -> x | |
| _, Leaf x, _ -> raise indexOutOfBounds | |
| _, Node (x, _, _), 0 -> x | |
| size, Node (x, left, right), index -> | |
let size' = size / 2 | |
in | |
if index <= size' | |
then | |
lookup (size', left, (index - 1)) | |
else | |
lookup (size', right, index - 1 - size') | |
let rec update = function | |
| _, Leaf x, 0, value -> Leaf value | |
| _, Leaf x, _, _ -> raise indexOutOfBounds | |
| _, Node (x, left, right), 0, value -> Node (value, left, right) | |
| size, Node (x, left, right), index, value -> | |
let size' = size / 2 | |
in | |
if index <= size' | |
then | |
Node (x, update (size', left, (index - 1), value), right) | |
else | |
Node (x, left, update (size', right, index - 1 - size', value)) | |
let rec toList = function | |
| Leaf x -> [x] | |
| Node (x, left, right) -> x :: toList left @ toList right | |
type RList<'a> = | |
| Nil | |
| Cons of (int * 'a tree) * RList<'a> | |
type rlist<'a> = RList<'a> | |
module RList = | |
let empty = Nil | |
let isEmpty = function | |
| Nil -> true | |
| _ -> false | |
let cons x = function | |
| Cons ((size1, t1), Cons ((size2, t2),rest)) as xs -> | |
if size1 = size2 | |
then | |
Cons ((1 + size1 + size2, Node (x, t1, t2)), rest) | |
else | |
Cons ((1, Leaf x), xs) | |
| rlist -> RList.Cons ((1, Leaf x), rlist) | |
let singleton x = | |
cons x Nil | |
let rec length = function | |
| Nil -> 0 | |
| Cons ((size, _), rest) -> size + length rest | |
let head = function | |
| Nil -> raise emptyList | |
| Cons ((_, Leaf x), _) -> x | |
| Cons ((_, Node (x, _, _)), _) -> x | |
let tail = function | |
| Nil -> raise emptyList | |
| Cons ((_, Leaf _), rest) -> rest | |
| Cons ((size, Node (_, left, right)), rest) -> | |
let size' = size / 2 | |
in Cons ((size', left), Cons ((size', right), rest)) | |
let rec nth index = function | |
| Nil -> raise indexOutOfBounds | |
| Cons ((size, tree), rest) -> | |
if index < size | |
then | |
Tree.lookup (size, tree, index) | |
else | |
nth (index - size) rest | |
let rec update index value = function | |
| Nil -> raise indexOutOfBounds | |
| Cons ((size, tree) as head, rest) -> | |
if index < size | |
then | |
Cons ((size, Tree.update (size, tree, index, value)), rest) | |
else | |
Cons (head, update (index - size) value rest) | |
let fromList list = | |
List.foldBack cons list Nil | |
let rec toList = function | |
| Nil -> [] | |
| Cons ((_, tree), rest) -> Tree.toList tree @ toList rest |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
module RandomAccessList | |
type Tree<'a> = | |
| Leaf of 'a | |
| Node of 'a * 'a Tree * 'a Tree | |
type RList<'a> = | |
| Nil | |
| Cons of (int * Tree<'a>) * RList<'a> | |
type tree<'a> = Tree<'a> | |
type rlist<'a> = RList<'a> | |
module RList = | |
val empty : 'a rlist | |
val cons : 'a -> 'a rlist -> 'a rlist | |
val singleton : 'a -> 'a rlist | |
val length : 'a rlist-> int | |
val head : 'a rlist -> 'a | |
val tail : 'a rlist -> 'a rlist | |
val nth : int -> 'a rlist -> 'a | |
val update : int -> 'a -> 'a rlist -> 'a rlist | |
val fromList : 'a list -> 'a rlist | |
val toList : 'a rlist -> 'a list |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment