Values of different types in an Array

48 views
Skip to first unread message

rvdalen

unread,
Dec 30, 2017, 2:18:44 AM12/30/17
to purescript
Hi everyone,

I am trying create an array of values, where the values are different types.
I am not interested in the concrete types, but really some common interface that
is shared between all the different concrete types.  For example, I want an array of
Showable values.

I have read the following posts on SO:

- https://stackoverflow.com/questions/35990022/how-can-i-create-an-array-with-polymorphic-data
- https://stackoverflow.com/questions/36006483/how-to-use-type-constrains-with-exists

but it is not clear to me how to achieve this.  The second URL embeds the `show` function into the value itself,
but what if we have a type class with 7 functions, then I would need to embed all 7 functions into the value itself
which seems like this approach does not scale well.

How can I embed the dictionary of the type class, rather than the individual functions into each value in the Array?

Happy holidays.
Regards
--Rouan

mszamot

unread,
Dec 30, 2017, 6:45:34 AM12/30/17
to pures...@googlegroups.com
Hi Roun,
You can use purescript-variant library to encode non homogeneous lists. 

There is an example 'allToString' which does almost what you wont.

Best regards, 
Marcin

 
Wysłano z telefonu Samsung
--
You received this message because you are subscribed to the Google Groups "purescript" group.
To unsubscribe from this group and stop receiving emails from it, send an email to purescript+...@googlegroups.com.
Visit this group at https://groups.google.com/group/purescript.
For more options, visit https://groups.google.com/d/optout.

Nathan Faubion

unread,
Dec 31, 2017, 12:54:16 PM12/31/17
to purescript
You cannot embed the dictionary directly in PureScript, as it doesn't have any compiler provided assistance for existential quantification like you would with Haskell GADTs. In PureScript, you would use the purescript-exists package or what I call the "existential" pattern, which is just avoiding the Exists wrapper and defining a constructor and eliminator through unsafe coercions to some foreign data type.

Here is an example of such a data type that embeds a dictionary and provides an eliminator that reifies it back as a constraint. This is very unsafe as it relies on dictionaries having a specific representation. try.purescript.org/?backend=core&gist=a61807ce8dd315f1c9716c8ca4cf3291


> The second URL embeds the `show` function into the value itself,
> but what if we have a type class with 7 functions, then I would need to embed all 7 functions into the value itself
> which seems like this approach does not scale well.

Doesn't scale well how? You always have to know what dictionaries you need to bundle whether or not you have compiler assistance or not. It's just boilerplate for you the library author. This pattern is pretty uncommon in practice. If you have a fixed set of variants, you can just write a wrapper ADT (most common), and if you want it to be extensible you can use purescript-variant to combine them (great for things like exception types, for example).

Nathan Faubion

unread,
Dec 31, 2017, 2:22:31 PM12/31/17
to purescript
To expand on it being uncommon, the above pattern would only be needed if you really needed to forget the type of something, and if you really needed to use polymorphic functions based on a dictionary. Existentials are isomorphic to a closure pairing (that is the above ShowBox is equivalent to `showBox :: forall a. Show a => a -> Unit -> String` where `showBox x = \_ -> show x`). Since you've forgotten the type anyway, all you can do is provide it to the show dictionary, which is the same as partial application. That means if you want to program against an abstract interface, you can instead build a record of partially applied functions instead of using all the Exists boilerplate. This is what purescript-halogen-vdom does, for example.

rvdalen

unread,
Jan 9, 2018, 12:41:13 AM1/9/18
to purescript
Thanks Marcin, Nathan

@Nathan:

What I mean with does not scale is that I need to manually create a `ShowDict` record.
This is fine for the Show type class as it only has 1 member, but what if I had a type class with 20 members?
I would need to create a FooDict record with 20 functions, one for each function in the Foo type class.

This seems like a lot of boilerplate code just to try to do something that seems conceptually simple :)

I will keep looking for a simpler solution for now.

Regards
--Rouan
Reply all
Reply to author
Forward
0 new messages