On 14 October 2010 08:34, Jacek Generowicz <[email protected]> wrote: > Those other data might be the functions' arguments, or they might be other > functions with which they are to be combined, or both.
You can represent these as existential packages. However, as Oleg shows you can always use skolemisation to eliminate the existential: http://okmij.org/ftp/Computation/Existentials.html This trick is basically what Brandon and Evan pointed out earlier when they suggested you replace the list :: [exists b. (b -> a, b)] with a list :: [a]. > Here's an example where lazy evaluation isn't enough: > > def memoize(fn): > cache = {} > def memoized_fn(*args): > if args not in cache: > cache[args] = fn(*args) > return cache[args] > return memoized_fn > > You memoize a function once, but it will be given different arguments, many > times, at a later time. I'm not sure why you would use existentials for this. Isn't the type of memoized_fn just :: Ord a => (a -> b) -> a -> b? This doesn't deal with argument *lists* so you may have to curry/uncurry to get functions of a different arity to go through, but that is IMHO a reasonable requirement for Haskell, where multi-argument functions do not have special status. (In the absence of side effects, I can't see an obvious way to implement it without some way to enumerate the domain "a" though. Conal Elliot uses type classes to solve this issue, see http://hackage.haskell.org/package/MemoTrie, where memo :: HasTrie t => (t -> a) -> t -> a). > will do. So please allow me to store (fnA1, fnA2) and (fnB1, fnB2) in the > same place. The program can tell that it can combine them with (.) because > the type of But if the only operation you ever do on this pair is (.), you may as well skolemise and just store (fnA1 . fnA2) directly. What is the advantage of doing otherwise? Max _______________________________________________ Haskell-Cafe mailing list [email protected] http://www.haskell.org/mailman/listinfo/haskell-cafe
