How can I create a list of various types that belong to the same class?

I have a configurable function that works on values that implement Generic class. I need to check it against several values, with several configurations. My first idea was to use the Array monad to obtain a Cartesian product of the set of values and the set of configurations. But the values must belong to a range of types in order for the test suite to be comprehensive. So how can I put my values, being of different types, into an array?

In plain JavaScript arrays can contain anything, so the problem does not exist. In Haskell, I would create a type such as data Wrapped = forall α. Generic α ⇒ Wrapped α, but it does require a few language extensions. I tried going this way in PureScript and it does not even parse. Is there a way to make it work?

1 Like

You’re looking for a feature called existential types. You can do this with the exists library: https://pursuit.purescript.org/packages/purescript-exists/4.0.0/docs/Data.Exists#t:Exists

Or you can alternatively do it with just regular functions:

newtype GenericBox =
  GenericBox (forall r. (forall a rep. Generic a rep => a -> r) -> r)

mkGenericBox :: forall a rep. Generic a rep => a -> GenericBox
mkGenericBox x = GenericBox \k -> k x

runGenericBox :: forall r.
  GenericBox ->
  (forall a rep. Generic a rep => a -> r) ->
  r
runGenericBox (GenericBox k) = k
4 Likes

I love your example, which is way more elegant than workarounds for this problem that I’ve used in the past! Would you mind elaborating on how you would use the exists library to do a similar thing? I can’t seem to figure out where to put the type class constraints in place.

1 Like

I think I’ve made a mistake, actually: I think Exists might only work in cases where you don’t need a constraint on the type you’re hiding.

1 Like

Ah that makes sense then. Still the example you posted is quite elegant and doesn’t introduce much boilerplate, thanks!

1 Like