
Hi Auke,
2. Is there a better way to define the types Blah, Yada, Blah' and Yada' (e.g. with less repetition)? After all, all I'm changing is the type of one field, but I end up having to redefine all my types.
I think one way to accomplish your task would be to employ functors as basic building blocks that you can parameterise to express either Blah or Blah' types. The complete code with my attempt is in the attachment. To get more information on Fix type I'd recommend to read on recursion schemes/F-algebras, e.g. https://github.com/willtim/recursion-schemes/raw/master/slides-final.pdf.
1. How can I write a function that takes a Blah, and outputs a Blah', and reports a nice error when there is no <blah> with the name specified in the <yada>? Can it be done at all without using partial functions like fromJust (when using Maybe to "report" errors)?
I included my attempt at defining such function in the attached code. The idea is that conversion works in the Either monad that allows to report errors. Monadic context is threaded through whole conversion, so if any error occurs it will appear in the result. However, the conversion function, resolveYadas, is still pure from the outside and you can easily find out whether there were any errors by analyzing the Either result. Sample run: λ> resolveYadas sampleEnv $ BlahF "first" 10 [YadaF "second"] Right (Fix (C (BlahF {blahName = "first", blahType = 10, blahYadas = [YadaF {yadaBlah = Fix (C (BlahF {blahName = "second", blahType = 3, blahYadas = []}))}]}))) λ> resolveYadas sampleEnv $ BlahF "first" 10 [YadaF "third"] Left "No Blah with name \"third\"" Hope this helps! Regards, Sergey