function [f,Y]=history_nest(fields,dim,H)
% history_nest - return state transformer that logs old states
%
% history :: 
%    F:{[N]->string}  ~'list of field names',
%    natural          ~'dimension to cat along (defaults to 1)',
%    struct F         ~'old history to build on'
% -> (history(A,F) ->history(A,F)),
%    history(A,F).
%
% history(A,F) ~ 'structure A with history of fields F' ::= 
%    struct { 
%       current :: struct A ~'original fields from A'; 
%       history :: struct F ~ 'sub-struct containing fields F'
%    }.
%
% This function returns a state transformer function. The state MUST be
% a structure but it can have any fields. The history mechanism adds the
% field 'history' which contains the histories of certain fields from 
% the main structure. The returned function concatenates the current
% values of the named fields onto the end of the corresponding fields
% in the history, if X is a sequence whose elements contain a field 
% called 'cost', then
%
%   [logcost,H0]=history({'cost'},1);
%   Y=scandata(logcost,H0,X);
%
% Elements of Y will have fields 'current' and 'history' which
% contain values from X and a history of 'cost' respectively.

	g=@logfields_scanner;
	if nargin<2, dim=1; end
	if nargin<3, H=struct; end

	for i=1:length(fields)
		% initialise history fields if not present already
		if ~isfield(H,fields{i}),
			H.(fields{i}) = [];
		end
	end
	
	f=@logfields;
	Y.current=[];
	Y.history=H;

	function Y=logfields(Y,X)
		Y.current=X;
		Y.history=logfields_scanner(Y.history,X);
	end

	function H=logfields_scanner(H,X)
		for i=1:length(fields)
			field=fields{i};
			H.(field) = cat(dim,H.(field),X.(field));
		end
	end
end
	
	


