Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

enabling TypeFamilies makes the code not build anymore

I have a module coded and working, however I can't manage to enter two function signatures for it, because to enter them I must enable the TypeFamilies extension for the module, and when I do that, it no longer builds.

For one of them I need TypeFamilies because it's using persisent/esqueleto functions.

The proper type would be, I believe:

getByIds :: (PersistEntityBackend a ~ SqlBackend) =>
   EntityField a (Key a) -> [Key a] -> SqlPersistM [Entity a]

(ghc suggests a more generic signature)

The other one uses hsqml.

ghc suggests this signature but I guess it could be simplified:

  prop :: forall tr b.
          (Marshal tr, Typeable b, MarshalMode tr ICanReturnTo () ~ Yes) =>
          String -> (b -> tr) -> Member (GetObjType (ObjRef b))

The bottom line is, that without TypeFamilies I cannot write those signatures. The moment I enable TypeFamilies, however, the code won't build, and I don't understand why. The error looks like some polymorphic functions suddenly became monomorphic.

The error output is relatively long, you can find it here.

I have TypeFamilies enabled in several other modules of the application without problems, and that enables me to write signatures using both the SqlBackend & ICanReturnTo constraints without problems.

Is there something wrong with that module that prevents it from building with TypeFamilies? Or should I enable yet another extension to fix it? I didn't expect just enabling that extension to break the compilation.

like image 340
Emmanuel Touzery Avatar asked Apr 08 '15 18:04

Emmanuel Touzery


1 Answers

The type equality constraint ~ can only be written out if you have either TypeFamilies or GADTs enabled.

However, enabling TypeFamilies or GADTs also enables MonoLocalBinds. As the name says, it disables generalization of locally defined variables.

If MonoLocalBinds prevents code from compiling, you should either write out the generalized type signatures or factor out such locals into top-level definitions. Sometimes writing out the generalized types is a bit difficult; in such cases you can try querying GHCi, or you can enable NoMonomorphismRestriction, write unannotated top-level definitions and then look at the inferred types.

like image 140
András Kovács Avatar answered Sep 18 '22 23:09

András Kovács