Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>Here's one way that kind of works. There are many more cases to cover if your fA fB have type variables in their inferred types. In that case the following code will have some pattern match failures at compile time.</p> <pre><code>{-# LANGUAGE FlexibleInstances, FunctionalDependencies, TemplateHaskell #-} import Language.Haskell.TH data A = A{ax::Int} deriving(Show) data B = B{bx::Int} deriving(Show) fA A{} i = i*(2 :: Int) fB B{} s1 s2 = "test"++s1++s2 class Func_f a b | a -&gt; b where f :: a -&gt; b let getLetter (AppT (AppT _ x) _) = x getSnd (AppT x y) = y mkInst name0 = do (VarI n ty _ _) &lt;- reify name0 fmap (:[]) $ instanceD (return []) [t| Func_f $(return $ getLetter ty) $(return $ getSnd ty) |] [valD (varP 'f) (normalB (varE name0)) []] in fmap concat $ mapM mkInst ['fB, 'fA] main :: IO () main = do let a = A 1 b = B 2 a_out = f a 5 b_out = f b "a" "b" print a_out print b_out </code></pre> <p>Whether this even helps you with the language you're compiling to haskell is another question.</p> <hr> <p><strong>Added Hints</strong></p> <p>If the type is polymorphic, you'll see reify giving something that isn't covered by my example code above.</p> <pre><code> &gt; :set -XTemplateHaskell &gt; :m +IPPrint Language.Haskell.TH &gt; putStrLn $(reify 'id &gt;&gt;= stringE . pshow) </code></pre> <p>Prints out something that describes (a->a):</p> <pre><code>VarI GHC.Base.id (ForallT [PlainTV a_1627394484] [] (AppT (AppT ArrowT (VarT a_1627394484)) (VarT a_1627394484))) Nothing (Fixity 9 InfixL) </code></pre> <p>With a bit of work, you could split that Type in there into the CxtQ and TypeQ that instanceD needs.</p> <p>I don't know how much sense it makes to generate (a->b) instead. You could go about replacing all type variables with new unique ones, which is probably best done with something like Data.Generics.everywhereM because data Type has many many constructors.</p> <p>You'll still have an issue that this is invalid:</p> <pre><code>instance Func_f (a -&gt; b) where f _ = id </code></pre> <p>This approach to getting (a->b) can make your program crash:</p> <pre><code>instance Func_f (a -&gt; b) where f _ = unsafeCoerce id </code></pre> <p>This approach lets the instance get chosen when the types are different, but at some later point in ghc's execution you can end up with a failure if 'a' and 'b' can't be the same.</p> <pre><code>instance (a~b) =&gt; Func_f (a-&gt;b) where f _ = unsafeCoerce id </code></pre>
    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