1

If I have a type data Foo = Foo Int Int where frequently (but not always) the second parameter is a (fixed) function of the first, I could write a helper function mkFoo m = Foo m (f m) to reduce duplication.

I have this exact problem, but at the type level. The natural solution might be to use singletons to promote f, but my f isn't easily promoted. Instead, I'm trying to use TemplateHaskell and reflection to evaluate f at compile time at the data level. For example, I can currently do this (using ‑XDataKinds and GHC.TypeLits):

f :: Integer -> Integer

data Bar (a::Nat) (b::Nat)

mkNat :: Integer -> Q Type -- constructs a TypeLit

bar :: Bar 5 $(mkNat $ f $ proxy natValue (Proxy::Proxy 5))

It's obviously annoying to have to write this with a concrete type every time I want to use this pattern. Unfortunately, I know of no shorter or generic way to write the signature for bar. In particular, I can't define the type synonym

type Bar' (m :: Nat) = Bar m $(mkNat $ f $ proxy natVal (Proxy::Proxy m))

bar :: Bar' 5

due to TH stage restrictions (m is not imported or known when compiling the synonym).

Is there any way to simplify the signature of bar?

crockeea
  • 21,651
  • 10
  • 48
  • 101
  • You would have to write e.g. `mkBar n = appT (conT ''Bar) (litT $ numTyLit n) \`appT\` (litT $ numTyLit $ f n)` and then `bar :: $(mkBar 5)`. There really is no way to put a splice like that into a type synonym. Unless it is strictly *impossible* to promote `f`, then it will probably be easier to do so (even if it is non-trivial) than dealing with TH in the long term. – user2407038 Mar 20 '16 at 18:26
  • Can you give a concrete example of your ultimate goal? Template Haskell always looks like line noise to me. – dfeuer Mar 21 '16 at 05:08
  • @dfeuer [This question](http://stackoverflow.com/questions/36062614/typelit-from-generic-integer-expression) goes into a little more detail, but it's basically what I've got there. At the top level, when I give concrete types, I (frequently) want one type parameter to be a function of another. The function (`f` above) is too hard to compute in my head, so this turns into a multi-step process. – crockeea Mar 21 '16 at 13:45

0 Answers0