[Haskell-cafe] Existential types (Was: Type vs TypeClass duality)
apfelmus at quantentunnel.de
apfelmus at quantentunnel.de
Thu Oct 25 12:18:36 EDT 2007
Ryan Ingram wrote:
> On 10/24/07, apfelmus <apfelmus at quantentunnel.de> wrote:
>> So, instead of storing a list [∃a. Show a => a], you may as well
>> store a
>> list of strings [String].
>
> I've seen this before, and to some extent I agree with it, but it
> breaks down for bigger examples due to sharing.
>
> In most cases, "x" has a more compact representation than the result
> of evaluating "show x". So if you keep a list of [show x, show y,
> show z] around for a long period of time, you're leaking space.
> Consider instead:
>
> data StringFn where
> StringFn :: forall a. a -> (a -> String) -> StringFn
>
> applyStringFn :: StringFn -> String
> applyStringFn (StringFn a f) = f a
>
> [ StringFn x show, StringFn y show, StringFn z show ]
>
> Now, you use more time every time you compute the result, but StringFn
> has a compact representation; you're not leaking the space used for
> the string throughout the execution of the program, but only
> allocating it while it's used.
Indeed. (Although the effect will be marginal in this particular
example since the unevaluated thunk (show x) is represented as
compactly as x . But the time-space trade-off would matter when
strings from the list are used several times.)
In a sense, that's also the reason why stream fusion à la Duncan +
Roman + Don uses an existential type
data Stream a where
Stream :: ∀s. s -> (s -> Step a s) -> Stream a
data Step a s = Done
| Yield a s
| Skip s
I mean, every stream can be represented by the list of its results but
the observation for fusion is that there is a much more compact
representation for the state (like an integer for [1..] or the source
list in map f . map g $ [x,y,...])
Regards,
apfelmus
More information about the Haskell-Cafe
mailing list