How do I specify types for a function, where they are not used in the function's arguments?
haskell, type-inference
Solution
GHC won't be able to infer the type variable `d`. You need to add it to the type signature itself, by adding a dummy argument. The standard trick is to use a proxy for this dummy argument, which means the caller doesn't need to give an actual value of that type.
You can get `Proxy` from the `tagged` package for GHC<7.8, or from `base` for GHC>=7.8, but for the purposes of the explanation I'll define it explicitly here:
data Proxy a = Proxy
standardInsert :: forall d . forall j .
(PersistEntityBackend d ~ SqlBackend,
PersistEntity d, SimpleJsonDataAccessConversion j d)
=> Proxy d -> j -> DatabaseEnvironmentT (Maybe (WithId j))
standardInsert _ json = do (...)
and then at a call site:
standardInsert (Proxy :: Proxy FooPersistentType) jsonValue
Problem
I'm writing some data-access routines, using Persistent. I want my API to be defined in terms of datatypes which represent JSON, but on the persistent side, my datatypes are defined by persistent's templating system. Given that I have mappings from json to database datatypes, and vice-versa, I thought I should be able to write generalised data access routines. All was going well until I tried to write the insert function: ``` standardInsert :: forall d . forall j . (PersistEntityBackend d ~ SqlBackend, PersistEntity d, SimpleJsonDataAccessConversion j d) => j -> DatabaseEnvironmentT (Maybe (WithId j)) standardInsert json = do maybeId <- runSqlMaybe $ insert db return $ toApi <$> maybeId where db = jsonToDataAccess json :: d -- Scoped type variable here. toApi key = addId key $ dataAccessToJson db ``` (`j` is the type variable for the JSON data type, `d` is the type variable for the persistent data type). This function has two type variables, `j` and `d`, but only `j` can be inferred from the arguments. In other words, if I call `standardInsert jsonValue`, the type variable `d` is ambiguous. I want to call it rather like in C++ - `standardInsert<FooJsonType, FooPersistentType>(jsonValue)`. How do I tell Haskell what `d` is? Or am I going about this in completely the wrong way?