Mercurial > hg > ishara
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);