The signature contexts in a mutually recursive group should all be identical

Robert van Herk rherk at cs.uu.nl
Mon May 9 11:04:15 EDT 2005


Hi all,

I am having a question about the "The signature contexts in a mutually 
recursive group should all be identical"-message. From what I understand 
from previous posts on this subject is that this is not strictly 
necessary, but is in the Haskell '98 specs, and that this error message 
only occurs in toy programs.

How ever, I think I am having a real example of a restriction caused by 
this message. The example is very big though (more than 1000 lines).

What it boils down to is the following:

I am writing a framework for website development. In this framework, a 
webpage, or a piece of a webpage, is called a component. I have 2 
important components, namely "def" and "myComp". myComp is being 
parametrized by some "accessors", i.e. functions that read and write 
IORefs. wfAction creates a link in the generated HTML code to another 
component. That is: when the client clicks that link, he will see the 
html generated by the component wfAction was parametrized by. In the 
example below, in def, when the client clicks "Click here for another 
component" in his webbrowser, he will see the contents of (myComp 
accessors). In myComp, I made a wfAction back to def. I *think* this 
should all work. However, I get a compile error, saying that the 
contexts of def and myComp are different:
    Contexts differ in length
    When matching the contexts of the signatures for
      myComp :: forall e r4 r2 r3 v.
                (AdmitChildHTML e,
                 WFReader r4 Int,
                 WFErrorWriter r2,
                 WFWriter r2 [Char],
                 WFErrorReader r2,
                 WFReader r2 String,
                 WFReader r3 v,
                 WFErrorReader r3,
                 WFWriter r3 String,
                 Show v,
                 WFErrorWriter r3) =>
                WFHTMLComponent (MyCompAccessors (R Bool) r2 r3 r4) e IO ()
      def :: forall e. (AdmitChildHTML e) => WFHTMLComponent' e IO ()


def :: AdmitChildHTML e => WFHTMLComponent' e IO ()
def =
  do {
       accessors <- liftIO $ myCompController;
       html
         (do doc_head
             body ( do text "Welcome"
                       br empty
                       wfAction "Click here for another component" 
(myComp accessors)
                  )
         )
       ;
     }

data MyCompAccessors r1 r2 r3 r4 =
  (WFReader r4 Int) =>
    MyCompAccessors {loginAccessors::(MyLoginAccessors r1 r2 r3), 
rReloadCount::r4}

myCompController :: IO (MyCompAccessors (R Bool) (RWE String) (RWE 
String) (R Int))
myCompController = ... --returns something that can read booleans, read 
and write strings, read and write strings, read integers

myComp :: (AdmitChildHTML e, WFReader r4 Int, WFErrorWriter r2,
                      WFWriter r2 [Char],
                      WFErrorReader r2,
                      WFReader r2 String,
                      WFReader r3 v,
                      WFErrorReader r3,
                      WFWriter r3 String,
                      Show v,
                      WFErrorWriter r3) => WFHTMLComponent 
(MyCompAccessors (R Bool) r2 r3 r4) e IO ()
myComp compAccessors =
  do {
       i <- wfRead (rReloadCount compAccessors);
       html ( do doc_head
                 body ( do text (
                                  "This is the  " ++
                                  (show i) ++
                                  "th time you are seeing this page 
within this session."
                                )
                           br empty
                           ... --include some other components
                           wfAction "Click here to see the default 
component again" def; --THIS IS WHAT MAKES IT ALL GO WRONG
                      )
            )           
       ;
     }

data MyLoginAccessors r1 r2 r3 =
  (WFReader r1 Bool,
   WFReader r2 String, WFWriter r2 String,
   WFReader r3 String, WFWriter r3 String
  ) => MyLoginAccessors {rLoggedIn::r1, rwLogin::r2, rwPasswd::r3}

myLoginController :: IO (MyLoginAccessors (R Bool) (RWE String) (RWE 
String))
myLoginController = ...


More information about the Glasgow-haskell-users mailing list