Last active
June 17, 2020 13:31
-
-
Save yonta/859cad60bc89e4bcb7cac69c3b1a8b78 to your computer and use it in GitHub Desktop.
破壊的デック
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
structure MutableDeque : | |
sig | |
type 'elem t | |
val empty : unit -> 'elem t | |
val cons : 'elem -> 'elem t -> 'elem t | |
val head : 'elem t -> 'elem | |
val tail : 'elem t -> 'elem t | |
val snoc : 'elem -> 'elem t -> 'elem t | |
val last : 'elem t -> 'elem | |
val init : 'elem t -> 'elem t | |
end | |
= | |
struct | |
datatype 'elem cell = Null | |
| Cell of | |
{ | |
prev: 'elem cell ref, | |
elem: 'elem, | |
next: 'elem cell ref | |
} | |
type 'elem t = {front: 'elem cell ref, rear: 'elem cell ref} | |
fun empty () = {front = ref Null, rear = ref Null} | |
fun cons elem {front, rear} = | |
case !front of | |
Null => | |
let | |
val cellPtr = | |
ref (Cell {prev = ref Null, elem = elem, next = ref Null}) | |
in | |
{front = cellPtr, rear = cellPtr} | |
end | |
| Cell _ => | |
let val newCell = (Cell {prev = ref Null, elem = elem, next = front}) | |
in {front = ref newCell, rear = rear} end | |
fun head {front, rear} = | |
case !front of | |
Null => raise Empty | |
| Cell {elem, ...} => elem | |
fun tail {front, rear} = | |
case !front of | |
Null => raise Empty | |
| Cell {next, ...} => | |
if front = rear then empty () | |
else {front = next, rear = rear} | |
fun snoc elem {front, rear} = | |
case !rear of | |
Null => | |
let | |
val cellPtr = | |
ref (Cell {prev = ref Null, elem = elem, next = ref Null}) | |
in | |
{front = cellPtr, rear = cellPtr} | |
end | |
| Cell _ => | |
let val newCell = (Cell {prev = rear, elem = elem, next = ref Null}) | |
in {front = front, rear = ref newCell} end | |
fun last {front, rear} = | |
case !rear of | |
Null => raise Empty | |
| Cell {elem, ...} => elem | |
fun init {front, rear} = | |
case !rear of | |
Null => raise Empty | |
| Cell {prev, ...} => | |
if front = rear then empty () | |
else {front = front, rear = prev} | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment