I would like to create an abstraction to use different template mechanisms:
class Template a where
process :: a -> Model -> IO String
class TemplateEngine a where
buildTemplate :: (Template b) => a -> BufferedReader -> IO b
My first attempt is to adapt Groovy templates so that I implement the necessary data types:
data GroovyWritable = mutable native groovy.lang.Writable where
native writeTo :: GroovyWritable -> Writer -> IO Writer
throws IOException
data GroovyTemplate = mutable native groovy.text.Template where
native make :: GroovyTemplate -> HashMap -> IO GroovyWritable
data GroovyEngine = mutable native groovy.text.markup.MarkupTemplateEngine where
native new :: () -> IO GroovyEngine
native createTemplate :: GroovyEngine -> BufferedReader -> IO GroovyTemplate
throws ClassNotFoundException, IOException
Then I made the appropriate instances:
instance Template GroovyTemplate where
process template model = do -- model is not used at the moment
config <- HashMap.new ()
writable <- GroovyTemplate.make template config
stWriter <- StringWriter.new ()
writer <- writable.writeTo stWriter
writer.toString
instance TemplateEngine GroovyEngine where
buildTemplate engine reader = GroovyEngine.createTemplate engine reader
But the compiler complains:
...
type `GroovyTemplate` is not as polymorphic as suggested
in the annotation where just `α` is announced.
...
type error in expression createTemplate engine reader
type is : IO GroovyTemplate
expected: IO α
Any ideas? Should I use a different strategy? Thanks
UPDATE
To explain what I'm trying to do, I add a function that represents a general way to build a template from a given template engine.
Suppose that I understand that Frege needs to be more accurate with respect to types, an instance TemplateEngineand BufferedReadercontaining the contents of a template file, performing the function of buildTemplatethis engine should give me an instance in return Template. This function is compiled here without any warnings.
execute :: (TemplateEngine a, Template b) => a -> BufferedReader -> IO b
execute engine reader = buildTemplate engine reader
, ? , ?
II ( ):
Ingo, , .
, TemplateEngine .
, , , . , , , , Template.
, html/json/xml... ..
execute :: (Template a) => a -> Model -> IO String
execute tpl model = tpl.process model
, production-ready :
execute :: (Template a) => a -> Model -> Either TemplateException String