extra type restrictions wanted?
Erik Zuurbier
F.S.A.Zuurbier@inter.nl.net
Thu, 1 Jan 1998 20:01:08 +0100 (MET)
/* One of the example programs in the Object IO library contains the
general function smap:
smap :: ((.s,.x) -> (.s,.y)) !(.s,![.x]) -> (!.s,![.y])
smap f (s,[x:xs])
# (s,y ) = f (s,x)
(s,ys) = smap f (s,xs)
= (s,[y:ys])
smap _ (s,_)
= (s,[])
Because of the order of the tuple elements, I think that this
function first computes the final value of s and only thereafter
releases the y-list. That makes it impossible to make this function
run in constant space. Very long lists may cause a 'heap full' error.
(Is this correct reasoning?)
Therefore I reversed the order of the tuple-elements. I also renamed
smap to mapFold, as it really combines map and fold: */
mapFold :: (a -> !.state -> (b,.state)) ![a] !.state -> ([b],.state)
mapFold fun [a:as] state
# (b,state) = fun a state
(bs,state) = mapFold fun as state
= ([b:bs],state)
mapFold fun [] state = ([],state)
/* This can run in constant space, delivering the output list elements
one by one to be further processed and discarded. But constant space
is achieved only if the 'state' parameter is strict in its components,
as in the example below.
*/
import StdEnv
:: *State = {sum :: !Int, count :: !Int}
Start :: ([Int],State)
Start = mapFold fun [1..10000] {sum=0,count=0}
where fun:: Int State -> (Int,State)
fun x {sum,count} = (x,{sum=sum+x,count=count+1})
/* My question is: if I regard it as the 'responsibility' of mapFold to
run in constant space, can I somehow rewrite it so that it will
actually do that, no matter what the type-details of the state parameter
are and independent of the fun-function?
Maybe it would be nice to be able to restrict application of mapFold
to state-parameters with strict components, in the spirit of class
restrictions.
Regards Erik Zuurbier
*/