Still struggling with this.&nbsp; If anyone has any constructive ideas?<br><br>I guess it&#39;s not really easy otherwise someone would have come up with a solution by now ;-)<br><br>The issue is the line in makeConstrM&#39;&#39; where we&#39;re trying to read (Data a =&gt; a) from (String).&nbsp; &quot;read&quot; doesnt work, because read needs a to be an instance of Read, and Data a does not enforce this.&nbsp; Whilst the parent class can be enforced to be Read, there&#39;s nothing to enforce this on the child.
<br><br>Anyway, took a look at SYB3, which came up with this little bit of code:<br><br>class Data a =&gt; StringParser a where<br>&nbsp;&nbsp; parsestring :: String -&gt; a<br>&nbsp;&nbsp; parsestring x = fst $ head $gread(x)<br>instance StringParser Int where
<br>&nbsp;&nbsp; parsestring x = read x<br>instance StringParser String where<br>&nbsp;&nbsp; parsestring x = read( &quot;\&quot;&quot; ++ x ++ &quot;\&quot;&quot; )<br><br>That looks like it should fix the problem with trying to read primitive child data types: we have a function &quot;parsestring&quot; with various custom methods for each data type we want to handle.&nbsp; On the face of it, it should work with any data type that is an instance of DAta, because of the default parsestring function.
<br><br>Unfortunately (and strangely) not: only data types explicitly added as instances will work with the default function for the Data class, even if the datatypes are in fact members of Data, and logically quite capable of running the default function.
<br><br>So, we cant use this for our Data a=&gt; String -&gt; a function<br><br>There&#39;s a bunch of &quot;ext&quot; functions that look potentially useful, but didnt manage to get any of them to work for this.&nbsp; If anyone has any ideas?
<br><br>For the moment, the only functions that build are:<br><br>return&nbsp; (fromJust $ fst $ head $ gread( &quot;(&quot; ++ (fromJust value) ++ &quot;)&quot; ) )<br><br>or:<br><br>return ((fromJust . cast) value)<br><br>... and neither of these work very well.&nbsp; The second works for strings only, not for other datatypes.&nbsp; The first just plain doesnt seem to work, for some reason. (By the way, if anyone knows how to extract debug information from partially executed functions that would be useful).
<br><br>Here&#39;s testConstrM&#39;&#39; at the moment:<br><br>testConstrM&#39;&#39; :: forall a. (Data a,Read a, Show a) =&gt; a -&gt; [(String, Maybe String, DataType,Constr)] -&gt; a<br>testConstrM&#39;&#39; templateobject fieldvalues = evalState (fromConstrM (do 
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; --value &lt;- gets head<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (fieldname,value,datatype,constr) &lt;- gets head<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; modify tail<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; --return (fromJust $ (readConstr datatype value) )<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; --return (parsestring (fromJust value))
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; --return (extR (fromJust $ fst $ head $ gread( &quot;(&quot; ++ (fromJust value) ++ &quot;)&quot; ) ) parsestring(fromJust value ) )<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return&nbsp; (fromJust $ fst $ head $ gread( &quot;(&quot; ++ (fromJust value) ++ &quot;)&quot; ) )
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; --return ((fromJust . cast) value)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; --case constr of<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; -- (toConstr(3::Int)) -&gt; return ((fromJust . cast) value)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; --IntConstr x -&gt; return ((fromJust . cast) value)<br>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; --_ -&gt; return ((fromJust . cast) value)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; --return (read_helper fieldname value datatype)<br>&nbsp;&nbsp; )(toConstr templateobject)) fieldvalues<br><br>You feed it a template object with the appropriate type, and an array of tuples with the fieldname, fieldvalue, datatype and constructor (we only use the fieldvalue at the moment, so you can leave the others blank).
<br><br>