<html><head></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space; ">Hi Wren,<div><br></div><div>I think that the ambiguity comes from the fact</div><div>that the type variable b is mentioned only </div><div>in the constraints and in the result type.</div><div><br></div><div>Crucially the instance B b selected determines the result b,</div><div>and this in general leads to ambiguity because instances</div><div>are chosen automatically behind the scenes.</div><div><br></div><div>A standard way to fix this is to include the ambiguous type b</div><div>among the types of the arguments.</div><div>With this trick it is possible to drive the instance choice to select</div><div>the correct one passing the right argument, avoiding any ambiguity.</div><div><br></div><div>For example you can use a Proxy b [1], to force the recursive</div><div>calls to reuse the same b. </div><div><br></div><div><div> foo :: (A a, B b) => a i -> Proxy b -> M (b i)<br> foo a p =<br> case view a of<br> ...<br> SomePattern a1 a2 -> do<br> b1 <- foo p a1<br> b2 <- foo p a2<br> return . unview $ SomePattern b1 b2<br></div></div><div><br></div><div>I hope this helps.</div><div><br></div><div>All the best,</div><div>Marco</div><div><br></div><div>[1] <a href="https://hackage.haskell.org/package/base-4.7.0.2/docs/Data-Proxy.html">https://hackage.haskell.org/package/base-4.7.0.2/docs/Data-Proxy.html</a></div><div><br></div><div><div><div>On 07/lug/2015, at 02.28, wren romano wrote:</div><br class="Apple-interchange-newline"><blockquote type="cite"><div>Hi all,<br><br>In my latest project I've been using a bunch of GADTs, which<br>unfortunately disables let-polymorphism (i.e., where-polymorphism) in<br>the most annoying way. For the most part I've been able to hack around<br>that limitation via judicious use of ScopedTypeVariables, but I've run<br>into an issue that I can't for the life of me figure out why GHC<br>doesn't like it.<br><br>I have something like the following function, where @a@ and @b@ happen<br>to be GADTs:<br><br> foo :: (A a, B b) => a i -> M (b i)<br> foo a =<br> case view a of<br> ...<br> SomePattern a1 a2 -> do<br> b1 <- foo a1<br> b2 <- foo a2<br> return . unview $ SomePattern b1 b2<br><br>It seems to me that the recursive calls should work just fine, using<br>the same @b@ as we'll ultimately be returning. However, for some<br>reason GHC complains about the recursive calls using some other @b0@<br>can can't deduce @B b0@ from @B b@. Why doesn't GHC unify these two<br>types? How can I force them to unify without adding type annotations<br>at every recursive call?<br><br>-- <br>Live well,<br>~wren<br>_______________________________________________<br>Haskell-Cafe mailing list<br><a href="mailto:Haskell-Cafe@haskell.org">Haskell-Cafe@haskell.org</a><br>http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe<br></div></blockquote></div><br></div></body></html>