I've read about generic programming in Haskell with the use of Generic
typeclass, as well as various older type-representations. (I've still haven't figured out the fine differences between the available stuff for this, the pros and cons. People did similar things before without Generic
, and it's not clear yet for me what it gives now additionally. But that's not the topic of this question.)
Is it possible to "reflect" in a similar way the interface of a module, so that I can programmatically accessthe list of exported functions (and types), and convert from a representation with a name of the function to the function.
My idea for using this is the following:
What is possible already: when the compiled program is run, it reads a formatted representation of data and evaluates a fixed function on it. (The format writer and reader are implemented by using the instances of a typeclass providing generic representations, like aeson or aeson-generic for formatting in JSON.)
Now I want to add another bit: the name of the function to call is read, too. It determines the type of the data, and the used reader for the data. Reads the input data, and evaluates the function on this data.
To save manually writing the module interface in a function which does this interaction, I thought there might be some approaches to module reflection similar to generics.
An example of reflection for types, data from http://ift.tt/18IpniP:
instance Generic (UserTree a) where
-- Representation type
type Rep (UserTree a) =
M1 D D1UserTree (
M1 C C1_0UserTree (
M1 S NoSelector (K1 R a)
:*: M1 S NoSelector (K1 R (UserTree a))
:*: M1 S NoSelector (K1 R (UserTree a)))
:+: M1 C C1_1UserTree U1)
-- Conversion functions
from (Node x l r) = M1 (L1 (M1 (M1 (K1 x) :*: M1 (K1 l) :*: M1 (K1 r))))
from Leaf = M1 (R1 (M1 U1))
to (M1 (L1 (M1 (M1 (K1 x) :*: M1 (K1 l) :*: M1 (K1 r))))) = Node x l r
to (M1 (R1 (M1 U1))) = Leaf
-- Meta-information
data D1UserTree
data C1_0UserTree
data C1_1UserTree
instance Datatype D1UserTree where
datatypeName _ = "UserTree"
moduleName _ = "Main"
instance Constructor C1_0UserTree where
conName _ = "Node"
instance Constructor C1_1UserTree where
conName _ = "Leaf"
Aucun commentaire:
Enregistrer un commentaire