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
?