function functional
% Collection of some simple functions to be written in the
% functional style.


%% Function Definitions

	% Compute the sum of a summable list using foldl
	% fsum :: [a] -> a
	function s = fsum(x)
		s = foldl( @(a,b)( ), , x );
	end

	% Compute the sum of a summable list using
	% tail recursion
	% fsum2 :: [a] -> a -> a
	function s = fsum2(x, acc)
		if isempty(x)
			s = ;
		else
			s = ;
		end;
	end

	% Compute the length of a list using foldl
	% flength :: [a] -> int
	function l = flength(x)
		l = foldl( @(a,b)( ), , x );
	end

	% Compute the length of a list using tail recursion
	% flength2 :: [a] -> int -> int
	function l = flength2(x, acc)
		if isempty(x)
			l = ;
		else
			l = ;
		end;
	end

	% Compute the inner product, or "dot product"
	% of two lists.
	% fdot :: [a] -> [a] -> a
	function p = fdot(x,y)
		if isempty(x) || isempty(y)
			p = 0;
		else
			p = ;
		end;
	end

	% This is a generalization of the dot product
	% generic_fdot :: (a->b->c) -> (c->c->c) -> c -> [a] -> [b] -> c
	function p = generic_fdot(f,g,i,x,y)
		if isempty(x) || isempty(y)
			p = i;
		else
			p = g(f(head(x),head(y)), generic_fdot(f,g,i,tail(x),tail(y)));
		end;
	end

	% We can implement the usual dot product by defining
	% a special case of the general form
	% fdot2 :: [a] -> [a] -> a
	function p = fdot2(x,y)
		p = generic_fdot( @(a,b)( ), @(a,b)( ), , x, y);
	end

	% Here we assign a name to a lambda expression, rather than
	% using MATLAB's function declaration syntax. This emphasizes
	% the way functions are "first class" values in the functional
	% approach.
	% fdot3 :: [a] -> [a] -> a
	fdot3 = @(x,y)( );

%% Function Applications
% Here, we test the functions written above.

x = [1 2 3 4 5]
y = [2 4 6 8 10]

disp(['length(x) = ' num2str(length(x)) ]);
disp(['flength(x) = ' num2str(flength(x)) ]);
disp(['flength2(x) = ' num2str(flength2(x,0)) ]);
disp(['length(y) = ' num2str(length(y)) ]);
disp(['flength(y) = ' num2str(flength(y)) ]);

disp(' ');
disp(['sum(x) = ' num2str(sum(x)) ]);
disp(['fsum(x) = ' num2str(fsum(x)) ]);
disp(['fsum2(x) = ' num2str(fsum2(x,0)) ]);
disp(['sum(y) = ' num2str(sum(y)) ]);
disp(['fsum(y) = ' num2str(fsum(y)) ]);

disp(' ');
disp(['dot(x,y) = ' num2str(dot(x,y)) ]);
disp(['fdot(x,y) = ' num2str(fdot(x,y)) ]);
disp(['fdot2(x,y) = ' num2str(fdot2(x,y)) ]);
disp(['fdot3(x,y) = ' num2str(fdot3(x,y)) ]);

end
