Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>I would venture to guess that the root of your problem is in the expression <code>with authSnaplet</code>. Here's why:</p> <pre><code>∀x. x ⊢ :t with authSnaplet with authSnaplet :: AuthUser u =&gt; m b (AuthSnaplet b1 u) a -&gt; m b v a </code></pre> <p>Don't mind the context, I filled in some bogus instances just to load stuff in GHCi. Note the type variables here--lots of ambiguity, and at least two that I expect you intend to be the same type. The easiest way to handle this is probably to create a small, auxiliary function with a type signature that narrows things down a bit, e.g.:</p> <pre><code>withAuthSnaplet :: (AuthUser u) =&gt; Handler a (AuthSnaplet b u) (Either AuthFailure u) -&gt; Handler a s (Either AuthFailure u) withAuthSnaplet = with authSnaplet </code></pre> <p>Again, pardon the nonsense, I don't actually have Snap installed at the moment, which makes things awkward. Introducing this function, and using it in place of <code>with authSnaplet</code> in <code>loginUser</code>, allows the code to type check for me. You may need to tweak things a bit to handle your actual instance constraints.</p> <hr> <p><strong>Edit:</strong> If the above technique doesn't let you nail down <code>b</code> by some means, and assuming that the types really are intended to be as generic as they're written, then <code>b</code> is impossibly ambiguous and there's no way around it. </p> <p>Using <code>with authSnaplet</code> eliminates <code>b</code> entirely from the actual type, but leaves it polymorphic with a class constraint on it. This is the same ambiguity that an expression like <code>show . read</code> has, with instance-dependent behavior but no way to pick one.</p> <p>To avoid this, you have roughly three choices:</p> <ul> <li><p>Retain the ambiguous type explicitly, so that <code>b</code> is found somewhere in the actual type of <code>loginUser</code>, not just the context. This may be undesirable for other reasons in the context of your application.</p></li> <li><p>Remove the polymorphism, by only applying <code>with authSnaplet</code> to suitably monomorphic values. If the types are known in advance, there's no room for ambiguity. This potentially means giving up some polymorphism in your handlers, but by breaking things apart you can limit the monomorphism to only code that cares what <code>b</code> is.</p></li> <li><p>Make the class constraints themselves unambiguous. If the three type parameters to <code>HasAuth</code> are, in practice, interdependent to some degree such that there will only be one valid instance for any <code>s</code> and <code>u</code>, then a functional dependency from the others to <code>b</code> would be completely appropriate.</p></li> </ul>
 

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