Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>This is due to the way in which type variables are scoped and quantified in standard Haskell. You can make the second version work like so:</p> <pre><code>{-# LANGUAGE RankNTypes, ScopedTypeVariables #-} module RigidProblem where data Wrapped a = Wrapped a alpha :: forall s. IO s -&gt; IO () alpha x = do rv &lt;- wrapit return () where wrapit :: IO (Wrapped s) wrapit = do a &lt;- x return (Wrapped a) </code></pre> <p>There are two changes: the RankNTypes and ScopedTypeVariables language extensions are enabled and the explicit <code>forall s</code> is added in the type signature of <code>alpha</code>. The first of the two extensions is what allows us to introduce the explicit <code>forall s</code> thus bringing the <code>s</code> into scope inside the body of <code>alpha</code>, whereas the second makes it so that the signature on <code>wrapit</code> is not taken by the type inference engine to contain an implicit <code>forall s</code> -- instead, the <code>s</code> in that signature is taken to name a type variable which should be in scope and is identified with it.</p> <p>The current default situation in Haskell, if I understand correctly, is that all rigid type variables (meaning type variables occurring in type signatures explicitly provided by the programmer) are implicitly quantified and <em>not</em> lexically scoped, so that there is no way to refer to a rigid type variable from an outer scope in an explicit signature provided in an inner scope... (Oh bother, I'm sure someone could phrase it better than this.) Anyway, from the type checker's point of view, the <code>s</code> in <code>alpha</code>'s signature and the one in <code>wrapit</code>'s signature are totally unrelated and cannot be unified -- thus the error.</p> <p>See <a href="http://www.haskell.org/ghc/docs/latest/html/users_guide/other-type-extensions.html#scoped-type-variables" rel="noreferrer">this page</a> from the GHC docs and <a href="http://hackage.haskell.org/trac/haskell-prime/wiki/ScopedTypeVariables" rel="noreferrer">this page</a> from Haskell Prime wiki for more information.</p> <p><strong>Update:</strong> I just realised that I never explained why the first version works. For the sake of completeness: note that with the first version, you could use <code>t</code> in place of <code>s</code> in <code>wrapit</code>'s signature and nothing would change. You could even take <code>wrapit</code> out of the <code>where</code> block and make it a separate top level function. The key point is that it is a polymorphic function, so that the type of <code>wrapit x</code> is determined by the type of <code>x</code>. No relation of the type variable used in the first version <code>wrapit</code>'s signature to that used in <code>alpha</code>'s signature would be of any use here. With the second version this is of course different and you have to resort to the above mentioned trickery to make <code>wrapit</code>'s <code>s</code> be the same thing as <code>alpha</code>'s <code>s</code>.</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload