signature SCANNER_SEQ =
sig
type 'a seq
val pull : 'a seq -> ('a * 'a seq) option
end
signature EXTENDED_SCANNER_SEQ =
sig
include SCANNER_SEQ
val null : 'a seq -> bool
val length : 'a seq -> int
val take_at_most : 'a seq -> int -> 'a list
end
functor ExtendScannerSeq (structure Seq : SCANNER_SEQ) : EXTENDED_SCANNER_SEQ =
struct
type 'a seq = 'a Seq.seq
val pull = Seq.pull
fun null s = is_none (pull s)
fun take_at_most s n =
if n <= 0 then [] else
case pull s of
NONE => []
| SOME (x,s') => x::(take_at_most s' (n-1))
fun length' s n =
case pull s of
NONE => n
| SOME (_, s') => length' s' (n+1)
fun length s = length' s 0
end
signature VECTOR_SCANNER_SEQ =
sig
include EXTENDED_SCANNER_SEQ
val fromString : string -> string seq
val fromVector : 'a Vector.vector -> 'a seq
end
structure VectorScannerSeq :> VECTOR_SCANNER_SEQ =
struct
structure Incubator : SCANNER_SEQ =
struct
type 'a seq = 'a Vector.vector * int * int
fun pull (v, len, i) = if i >= len then NONE else SOME (Vector.sub (v, i), (v, len, i+1))
end
structure Extended = ExtendScannerSeq (structure Seq = Incubator)
open Extended
fun fromVector v = (v, Vector.length v, 0)
fun vector_from_string s = Vector.tabulate (String.size s, fn i => String.str (String.sub (s, i)))
fun fromString s = fromVector (vector_from_string s)
end
signature LIST_SCANNER_SEQ =
sig
include EXTENDED_SCANNER_SEQ
val fromString : string -> string seq
val fromList : 'a list -> 'a seq
end
structure ListScannerSeq :> LIST_SCANNER_SEQ =
struct
structure Incubator : SCANNER_SEQ =
struct
type 'a seq = 'a list
fun pull [] = NONE
| pull (x::xs) = SOME (x, xs)
end
structure Extended = ExtendScannerSeq (structure Seq = Incubator)
open Extended
val fromList = I
val fromString = explode
end