 <p>There is a problem with different number of arguments.</p> <p>The simplest way is to use data type for "parameters". And to use data type for "result".</p> <p>And to use just pattern-matching instead of class.</p> <p>Something like that:</p> <pre><code>type GreenMix a = (Scalar a, Complex (Scalar a)) data ResultType a = Clomb (Scalar a) | Lrenz (Complex (Scalar a)) | Mix (GreenMix a) data Gauge a = Gauge1 (Scalar a) (Scalar a) | Gauge2 (Scalar a) (Scalar a) (Scalar a) greenF :: (Scalar a -&gt; a) -&gt; (Scalar a -&gt; a) -&gt; Gauge a -&gt; Result a greenF f1 f2 (Gauge1 g1 g2) = Clomb $ greenF_Gauge1 f1 f2 g1 g2 greenF f1 f2 (Gauge2 g1 g2 g3) = Lrenz $ greenF_Gauge2 f1 f2 g1 g2 g3 </code></pre>