Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>Here's a suggestion to solve a more general problem, not yours specifically (I need more detail yet first - I promise to check later). I'm writing it in case other people are searching for a solution to a similar problem to you, I certainly was in the past, before I discovered SO. SO is especially great when it helps you try a radically new approach.</p> <p>I used to have the work habit:</p> <ol> <li>Introduce a multi-parameter type class (Types hanging out all over the place, so...)</li> <li>Introduce functional dependencies (Should tidy it up but then I end up needing...)</li> <li>Add FlexibleInstances (Alarm bells start ringing. There's a reason the compiler has this off by default...)</li> <li>Add UndecidableInstances (GHC is telling you you're on your own, because it's not convinced it's up to the challenge you're setting it.)</li> <li>Everything blows up. Refactor somehow.</li> </ol> <p>Then I discovered the joys of <a href="http://www.haskell.org/haskellwiki/Simonpj/Talk%3aFunWithTypeFuns" rel="nofollow">type families</a> (functional programming for types (hooray) - multi-parameter type classes are (a bit like) logic programming for types). My workflow changed to:</p> <ol> <li><p>Introduce a type class including an associated type, i.e. replace</p> <pre><code>class MyProblematicClass a b | a -&gt; b where thing :: a -&gt; b thang :: b -&gt; a -&gt; b </code></pre> <p>with</p> <pre><code>class MyJustWorksClass a where type Thing a :: * -- Thing a is a type (*), not a type constructor (* -&gt; *) thing :: a -&gt; Thing a thang :: Thing a -&gt; a -&gt; Thing a </code></pre></li> <li><p>Nervously add FlexibleInstances. Nothing goes wrong at all.</p></li> <li>Sometimes fix things by using constraints like <code>(MyJustWorksClass j,j~a)=&gt;</code> instead of <code>(MyJustWorksClass a)=&gt;</code> or <code>(Show t,t ~ Thing a,...)=&gt;</code> instead of <code>(Show (Thing a),...) =&gt;</code> to help ghc out. (<code>~</code> essentially means 'is the same type as')</li> <li>Nervously add FlexibleContexts. Nothing goes wrong at all.</li> <li>Everything works.</li> </ol> <p>The reason "Nothing goes wrong at all" is that ghc <em>calculates</em> the type <code>Thing a</code> using my type function <code>Thang</code> rather than trying to <em>deduce</em> it using a merely a bunch of assertions that there's a function there and it ought to be able to work it out. </p> <p>Give it a go! Read <a href="http://www.haskell.org/haskellwiki/Simonpj/Talk%3aFunWithTypeFuns" rel="nofollow">Fun with Type Functions</a> <em>before</em> reading the <a href="http://www.haskell.org/haskellwiki/GHC/Type_families" rel="nofollow">manual</a>!</p>
 

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