src/Pure/sequence.ML
changeset 1458 fd510875fb71
parent 720 e6cf828a0c67
child 1460 5a6f2aabd538
equal deleted inserted replaced
1457:ad856378ad62 1458:fd510875fb71
     1 (*  Title: 	sequence
     1 (*  Title:      sequence
     2     ID:         $Id$
     2     ID:         $Id$
     3     Author: 	Lawrence C Paulson, Cambridge University Computer Laboratory
     3     Author:     Lawrence C Paulson, Cambridge University Computer Laboratory
     4     Copyright   1988  University of Cambridge
     4     Copyright   1988  University of Cambridge
     5 
     5 
     6 Unbounded sequences implemented by closures.
     6 Unbounded sequences implemented by closures.
     7 
     7 
     8 RECOMPUTES if sequence is re-inspected.
     8 RECOMPUTES if sequence is re-inspected.
    12 
    12 
    13 
    13 
    14 signature SEQUENCE = 
    14 signature SEQUENCE = 
    15   sig
    15   sig
    16   type 'a seq
    16   type 'a seq
    17   val append	: 'a seq * 'a seq -> 'a seq
    17   val append    : 'a seq * 'a seq -> 'a seq
    18   val chop	: int * 'a seq -> 'a list * 'a seq
    18   val chop      : int * 'a seq -> 'a list * 'a seq
    19   val cons	: 'a * 'a seq -> 'a seq
    19   val cons      : 'a * 'a seq -> 'a seq
    20   val filters	: ('a -> bool) -> 'a seq -> 'a seq
    20   val filters   : ('a -> bool) -> 'a seq -> 'a seq
    21   val flats	: 'a seq seq -> 'a seq
    21   val flats     : 'a seq seq -> 'a seq
    22   val hd	: 'a seq -> 'a
    22   val hd        : 'a seq -> 'a
    23   val interleave: 'a seq * 'a seq -> 'a seq
    23   val interleave: 'a seq * 'a seq -> 'a seq
    24   val its_right	: ('a * 'b seq -> 'b seq) -> 'a seq * 'b seq -> 'b seq
    24   val its_right : ('a * 'b seq -> 'b seq) -> 'a seq * 'b seq -> 'b seq
    25   val list_of_s	: 'a seq -> 'a list
    25   val list_of_s : 'a seq -> 'a list
    26   val mapp	: ('a -> 'b) -> 'a seq -> 'b seq -> 'b seq
    26   val mapp      : ('a -> 'b) -> 'a seq -> 'b seq -> 'b seq
    27   val maps	: ('a -> 'b) -> 'a seq -> 'b seq
    27   val maps      : ('a -> 'b) -> 'a seq -> 'b seq
    28   val null	: 'a seq
    28   val null      : 'a seq
    29   val prints	: (int -> 'a -> unit) -> int -> 'a seq -> unit
    29   val prints    : (int -> 'a -> unit) -> int -> 'a seq -> unit
    30   val pull	: 'a seq -> ('a * 'a seq) option
    30   val pull      : 'a seq -> ('a * 'a seq) option
    31   val s_of_list	: 'a list -> 'a seq
    31   val s_of_list : 'a list -> 'a seq
    32   val seqof	: (unit -> ('a * 'a seq) option) -> 'a seq
    32   val seqof     : (unit -> ('a * 'a seq) option) -> 'a seq
    33   val single	: 'a -> 'a seq
    33   val single    : 'a -> 'a seq
    34   val tl	: 'a seq -> 'a seq
    34   val tl        : 'a seq -> 'a seq
    35   end;
    35   end;
    36 
    36 
    37 
    37 
    38 functor SequenceFun () : SEQUENCE = 
    38 functor SequenceFun () : SEQUENCE = 
    39 struct
    39 struct
    65 fun chop (n:int, s: 'a seq): 'a list * 'a seq =
    65 fun chop (n:int, s: 'a seq): 'a list * 'a seq =
    66   if n<=0 then ([],s)
    66   if n<=0 then ([],s)
    67   else case pull(s) of
    67   else case pull(s) of
    68            None => ([],s)
    68            None => ([],s)
    69          | Some(x,s') => let val (xs,s'') = chop (n-1,s')
    69          | Some(x,s') => let val (xs,s'') = chop (n-1,s')
    70 		         in  (x::xs, s'')  end;
    70                          in  (x::xs, s'')  end;
    71 
    71 
    72 (*conversion from sequence to list*)
    72 (*conversion from sequence to list*)
    73 fun list_of_s (s: 'a seq) : 'a list = case pull(s) of
    73 fun list_of_s (s: 'a seq) : 'a list = case pull(s) of
    74         None => []
    74         None => []
    75       | Some(x,s') => x :: list_of_s s';
    75       | Some(x,s') => x :: list_of_s s';
    82 
    82 
    83 (*functional to print a sequence, up to "count" elements
    83 (*functional to print a sequence, up to "count" elements
    84   the function prelem should print the element number and also the element*)
    84   the function prelem should print the element number and also the element*)
    85 fun prints (prelem: int -> 'a -> unit) count (s: 'a seq) : unit =
    85 fun prints (prelem: int -> 'a -> unit) count (s: 'a seq) : unit =
    86   let fun pr (k,s) = 
    86   let fun pr (k,s) = 
    87 	   if k>count then ()
    87            if k>count then ()
    88 	   else case pull(s) of
    88            else case pull(s) of
    89 	       None => ()
    89                None => ()
    90 	     | Some(x,s') => (prelem k x;  prs"\n";  pr (k+1, s'))
    90              | Some(x,s') => (prelem k x;  prs"\n";  pr (k+1, s'))
    91   in  pr(1,s)  end;
    91   in  pr(1,s)  end;
    92 
    92 
    93 (*Map the function f over the sequence, making a new sequence*)
    93 (*Map the function f over the sequence, making a new sequence*)
    94 fun maps f xq = seqof (fn()=> case pull(xq) of
    94 fun maps f xq = seqof (fn()=> case pull(xq) of
    95         None       => None
    95         None       => None
    96       | Some(x,yq) => Some(f x,  maps f yq));
    96       | Some(x,yq) => Some(f x,  maps f yq));
    97 
    97 
    98 (*Sequence append:  put the elements of xq in front of those of yq*)
    98 (*Sequence append:  put the elements of xq in front of those of yq*)
    99 fun append (xq,yq)  =
    99 fun append (xq,yq)  =
   100   let fun copy xq = seqof (fn()=>
   100   let fun copy xq = seqof (fn()=>
   101 	    case pull xq of  
   101             case pull xq of  
   102 		 None       => pull yq
   102                  None       => pull yq
   103 	       | Some(x,xq') => Some (x, copy xq'))
   103                | Some(x,xq') => Some (x, copy xq'))
   104   in  copy xq end;
   104   in  copy xq end;
   105 
   105 
   106 (*Interleave elements of xq with those of yq -- fairer than append*)
   106 (*Interleave elements of xq with those of yq -- fairer than append*)
   107 fun interleave (xq,yq) = seqof (fn()=>
   107 fun interleave (xq,yq) = seqof (fn()=>
   108       case pull(xq) of  
   108       case pull(xq) of  
   109           None       => pull yq
   109           None       => pull yq
   110 	| Some(x,xq') => Some (x, interleave(yq, xq')));
   110         | Some(x,xq') => Some (x, interleave(yq, xq')));
   111 
   111 
   112 (*map over a sequence xq, append the sequence yq*)
   112 (*map over a sequence xq, append the sequence yq*)
   113 fun mapp f xq yq =
   113 fun mapp f xq yq =
   114   let fun copy s = seqof (fn()=> 
   114   let fun copy s = seqof (fn()=> 
   115             case pull(s) of
   115             case pull(s) of
   116 	        None       => pull(yq)
   116                 None       => pull(yq)
   117               | Some(x,xq') => Some(f x, copy xq'))
   117               | Some(x,xq') => Some(f x, copy xq'))
   118   in  copy xq end;
   118   in  copy xq end;
   119 
   119 
   120 (*Flatten a sequence of sequences to a single sequence. *)
   120 (*Flatten a sequence of sequences to a single sequence. *)
   121 fun flats ss = seqof (fn()=> case pull(ss) of
   121 fun flats ss = seqof (fn()=> case pull(ss) of
   124 
   124 
   125 (*accumulating a function over a sequence;  this is lazy*)
   125 (*accumulating a function over a sequence;  this is lazy*)
   126 fun its_right (f: 'a * 'b seq -> 'b seq) (s: 'a seq, bstr: 'b seq) : 'b seq =
   126 fun its_right (f: 'a * 'b seq -> 'b seq) (s: 'a seq, bstr: 'b seq) : 'b seq =
   127   let fun its s = seqof (fn()=>
   127   let fun its s = seqof (fn()=>
   128             case pull(s) of
   128             case pull(s) of
   129 	        None       => pull bstr
   129                 None       => pull bstr
   130 	      | Some(a,s') => pull(f(a, its s')))
   130               | Some(a,s') => pull(f(a, its s')))
   131   in  its s end; 
   131   in  its s end; 
   132 
   132 
   133 fun filters pred xq =
   133 fun filters pred xq =
   134   let fun copy s = seqof (fn()=> 
   134   let fun copy s = seqof (fn()=> 
   135             case pull(s) of
   135             case pull(s) of
   136 	        None       => None
   136                 None       => None
   137               | Some(x,xq') => if pred x then Some(x, copy xq')
   137               | Some(x,xq') => if pred x then Some(x, copy xq')
   138 			       else pull (copy xq') )
   138                                else pull (copy xq') )
   139   in  copy xq end
   139   in  copy xq end
   140 
   140 
   141 end;
   141 end;