启用TypeFamilies使代码不再构建

时间:2015-04-08 18:41:20

标签: haskell ghc type-families

我有一个编码和工作的模块,但是我无法为它输入两个功能签名,因为输入它们我必须为模块启用TypeFamilies扩展名,当我这样做时,它不再建立。

对于其中一个,我需要TypeFamilies,因为它使用的是persisent/esqueleto functions

我认为合适的类型是:

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

(ghc建议更通用的签名)

另一个使用hsqml

ghc建议使用此签名,但我想它可以简化:

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

底线是,没有TypeFamilies我无法写出这些签名。然而,当我启用TypeFamilies时,代码不会构建,我也不明白为什么。错误看起来像一些多态函数突然变成单态。

错误输出相对较长,您可以找到它here

我在应用程序的其他几个模块中启用了TypeFamilies而没有任何问题,这使我能够使用SqlBackend和& ICanReturnTo约束没有问题。

该模块是否存在问题导致无法使用TypeFamilies进行构建?或者我应该启用另一个扩展来修复它吗?我没想到只是启用该扩展来打破编译。

1 个答案:

答案 0 :(得分:9)

如果您启用了~TypeFamilies,则只能写出类型等式约束GADTs

但是,启用TypeFamiliesGADTs也会启用MonoLocalBinds.正如名称所示,它会禁用本地定义变量的泛化。

如果MonoLocalBinds阻止编译代码,您应该写出通用类型签名,或将这些本地因素分解为顶级定义。有时写出广义类型有点困难;在这种情况下,您可以尝试查询GHCi,或者您可以启用NoMonomorphismRestriction,编写未注释的顶级定义,然后查看推断的类型。