Type not as polymorphic as suggested

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
+4
1

, , , GroovyEngine.createTemplate GroovyEngine TemplateEngine. buildTemplate promises Template, , , Template .

, . , frege, Template. , , , Template . GroovyEngine.createTemplate , , , .

+1

Source: https://habr.com/ru/post/1624910/


All Articles