Is it possible to do heterogeneous Data.Map
in Haskell with GADT
instead of Dynamic
? I tried to model heterogeneous collection as laid out in this answer:
{-# LANGUAGE GADTs #-}
class Contract a where
toString :: a -> String
data Encapsulated where
Encapsulate :: Contract a => a -> Encapsulated
getTypedObject :: Encapsulated -> a
getTypedObject (Encapsulate x) = x
The idea being that Encapsulated
could be used to store different objects of TypeClass a
, and then extracted at run-time for specific type.
I get error about type of x
not matching Contract a
. Perhaps I need to specify some kind of class constraints to tell GHC
that type of x
in Encapsulate x
is same as a
in Contract a
?
T.hs:10:34:
Couldn't match expected type ‘a’ with actual type ‘a1’
‘a1’ is a rigid type variable bound by
a pattern with constructor
Encapsulate :: forall a. Contract a => a -> Encapsulated,
in an equation for ‘getTypedObject’
at T.hs:10:17
‘a’ is a rigid type variable bound by
the type signature for getTypedObject :: Encapsulated -> a
at T.hs:9:19
Relevant bindings include
x :: a1 (bound at T.hs:10:29)
getTypedObject :: Encapsulated -> a (bound at T.hs:10:1)
In the expression: x
In an equation for ‘getTypedObject’:
getTypedObject (Encapsulate x) = x
I am trying this approach because I have JSON objects of different types, and depending on the type that is decoded at run-time over the wire, we want to retrieve appropriate type-specific builder
from Map
(loaded at run-time IO in main
from configuration files, and passed to the function) and pass it decoded JSON data of the same type.
Dynamic
library would work here. However, I am interested in finding out if there are other possible approaches such as GADTs
or datafamilies
.