changeset 30:28c9ff839f38

Added nil for empty sequence, unfold is now infinite, concat takes only seq(seq(A)),, must use concatseqs for cell array of sequences; added rndmap as special case of rndzip.
author samer
date Sat, 19 Jan 2013 18:27:00 +0000
parents 61921dceded1
children 8cc4f326fc66
files README.txt sequences/+seq/nil.m sequences/+seq/unfold_finite.m sequences/@seq/seq.m sequences/@seq/skin.m sequences/concatseqs.m sequences/nil.m sequences/rndmap.m sequences/unfold.m
diffstat 9 files changed, 134 insertions(+), 3 deletions(-) [+]
line wrap: on
line diff
--- a/README.txt	Sat Jan 19 17:56:21 2013 +0000
+++ b/README.txt	Sat Jan 19 18:27:00 2013 +0000
@@ -132,18 +132,26 @@
     array, to represent a list of argument or return types.
 
     A comma separated list is literally a sequence of things separated by commas, eg
+
 	    A, B, C, D
+
     such as those that appear in various places in Matlab code, eg,
+
 	    [<list>] = f(1,<list>);
 		 x = [<list>];
 		 y= x(<list>);
 
     If A is a cell-array containing N elements, ie A = { a1, a2, ..., aN }
     then A{:} denotes a comma-separated list of its elements, ie
+
 	    A{:}   ==  A{1}, A{2}, ..., A{N}
+
     So, if A and B are lists of types, eg A = { real, natural } and B = {[[2,2]], real }, then
+
 	    A{:} -> B{:}   <denotes>   real, natural -> [[2,2]], real
+
     ie, a valid function type. Similarly, 
+
 	    cell A == cell {A{:}} == cell {real, natural} == pair(real,natural)
 
     If a variable such as A is used in a type specification, and we wish to emphasise
@@ -155,7 +163,7 @@
         {[N]->type} - list of N types
 
     For example, consider the last_ret which calls a given function with a list of
-	 arguments, gets all the return values and returns the last one:
+    arguments, gets all the return values and returns the last one:
 
 	    function  y=last_ret(f,varargin)
 			 R=cell(1,nargout(f));
@@ -170,10 +178,34 @@
 			 A{1:N}           ~'N further arguments matching types in A'
 		 -> B{M}             ~'the first return value'.
 
+     This type list business has finally resolved the question of how to type functions
+     that take no arguments or return nothing: I had originally used a Haskellish
+	  'unit' type, but strictly speaking, this denotes a type with only one value, say
+	  (). This doesn't really work for Matlab. Instead, let Z be an empty list, ie Z={}.
+	  We then let void denote Z{:}, that is, an empty comma separated list. This means
+	  that void now truly denotes 0 types, not one degenerate type.
+
+
   User-defined types
 
      Further types can be defined either as type synonyms written as A ::= B, where
      A is the new type and B is an existing type, or in terms of user-defined Matlab
-	  classes, such as the sequence, signal and arrow types in this library.
-     
+     classes, such as the sequence, signal and arrow types in this library.
 
+     For, the arrow type is written as
+
+	     arrow(A,B,C)
+
+     where A is a list of input types, B is a list of output types, and C is a state 
+	  type. This could be made clearer with explicit type decorations:
+
+	     arrow(A@typelist(N),B@typelist(M),C)
+
+     Internally, each arrow results in a structure containing functions:
+
+        struct {
+           proc     :: A{:} => B{:};
+           getstate :: void => C;
+			  ...
+        }
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/sequences/+seq/nil.m	Sat Jan 19 18:27:00 2013 +0000
@@ -0,0 +1,14 @@
+% nil - empty sequence constructor
+%
+% nil :: void -> seq(_).
+classdef nil < seq
+	methods
+		function o=nil, end
+		function x=head(o), error('nil: no head'); end
+		function b=next(o), error('nil: no next'); end
+		function z=elsize(o), z=[nan,nan]; end
+		function s=tostring(o), s='nil'; end
+		function f=isempty(o), f=true; end
+	end
+end
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/sequences/+seq/unfold_finite.m	Sat Jan 19 18:27:00 2013 +0000
@@ -0,0 +1,42 @@
+% unfold_finite - sequence obtained by iterating fn over state
+%
+% unfold_finite :: 
+%    (S->A,S)	~'unfolding function',
+%    S         ~ initial state,
+% -> unfold_finite(S,A) < seq(A).
+%
+% NB. The empty array [] is a special value for the state
+% meaning there are no more elements in the sequence. You
+% cannot use [] as a normal state value.
+classdef unfold_finite < seq
+	properties (GetAccess=private, SetAccess=immutable)
+		fn
+	end
+	properties (GetAccess=private, SetAccess=private)
+		value
+		state
+	end
+	methods (Static)
+		function d=make(f,s0)
+			xs=f(s0);
+			if isempty(xs), d=nil; else d=unfold_finite(f,xs{2},xs{1}); end
+		end
+	end
+	methods
+		function d=unfold_finite(f,s,x)
+			d.value=x;
+			d.state=s;
+			d.fn=f; 	% function to apply 
+		end
+
+		function s=elsize(o), s=size(o.value); end
+		function s=tostring(o), s=sprintf('unfold_finite(%s,%s)',tostring(o.fn),tostring(o.state)); end
+		function x=head(o), x=o.value; end
+		function o=next(o) 
+			xs=o.fn(o.state);
+			if isempty(xs), o=nil;
+			else o.value=xs{1}; o.state=xs{2};
+			end
+		end
+	end
+end
--- a/sequences/@seq/seq.m	Sat Jan 19 17:56:21 2013 +0000
+++ b/sequences/@seq/seq.m	Sat Jan 19 18:27:00 2013 +0000
@@ -1,5 +1,9 @@
 % seq - Base class for sequences
 classdef seq 
+   properties (Constant, GetAccess=public)
+	   NIL = seq.nil
+	end
+
 	methods (Abstract)
 		x=head(a)     % seq(A) -> A.
 		b=next(a)     % seq(A) -> seq(A).
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/sequences/@seq/skin.m	Sat Jan 19 18:27:00 2013 +0000
@@ -0,0 +1,6 @@
+% skin - Change textual representation of sequence
+%
+% skin :: seq(A), (seq(A)->string) -> seq(A).
+function y=skin(s,strfn), 
+	if isempty(s), y=nil; else y=seq.skin(s,strfn); end
+end
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/sequences/concatseqs.m	Sat Jan 19 18:27:00 2013 +0000
@@ -0,0 +1,9 @@
+% concatseqs - Concatenate sequences in cell array
+%
+% concatseqs ::
+%    {[N]->seq(A)}	~ 'cell array of N sequences',
+% -> seq(A)          ~ 'resultant sequence'.
+function o=concat(sources)
+	if iscell(sources), sources=cellseq(sources); end
+	o=seq.concat.make(cellseq(sources));
+end
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/sequences/nil.m	Sat Jan 19 18:27:00 2013 +0000
@@ -0,0 +1,5 @@
+% nil - empty sequence constructor
+%
+% nil :: void -> seq(_).
+function s=nil, s=seq.NIL; end
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/sequences/rndmap.m	Sat Jan 19 18:27:00 2013 +0000
@@ -0,0 +1,11 @@
+function X=rndmap(gen,x,rs)
+% rndzip - Random sequence by zipping argument sequences
+%
+% rndzip ::
+%    (A -> rndgen B) ~'sampling function',
+%    seq A1          ~'argument sequences', 
+%    rndstate        ~'initial random state'
+% -> seq B.
+X=rndzip(gen,x,rs);
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/sequences/unfold.m	Sat Jan 19 18:27:00 2013 +0000
@@ -0,0 +1,8 @@
+% unfold - sequence obtained by iterating fn over state
+%
+% unfold :: 
+%    (S->A,S)	~'unfolding function',
+%    S         ~ initial state,
+% -> unfold(S,A) < seq(A).
+
+function y=unfold(f,s0), y=seq.unfold(f,s0);