启用 TypeFamilies 使代码不再构建
enabling TypeFamilies makes the code not build anymore
我有一个模块编码并且可以工作,但是我无法为它输入两个函数签名,因为要输入它们我必须为模块启用 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
进行构建?或者我应该启用另一个扩展来修复它吗?没想到只启用那个扩展就破坏了编译。
类型等式约束 ~
只有在启用 TypeFamilies
或 GADTs
时才能写出。
但是,启用 TypeFamilies
或 GADTs
也会启用 MonoLocalBinds
. 顾名思义,它会禁用局部定义变量的泛化。
如果 MonoLocalBinds
阻止代码编译,您应该写出通用类型签名或将此类局部变量分解为顶级定义。有时写出泛化类型有点困难;在这种情况下,您可以尝试查询 GHCi,或者您可以启用 NoMonomorphismRestriction
,编写未注释的顶级定义,然后查看推断的类型。
我有一个模块编码并且可以工作,但是我无法为它输入两个函数签名,因为要输入它们我必须为模块启用 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
进行构建?或者我应该启用另一个扩展来修复它吗?没想到只启用那个扩展就破坏了编译。
类型等式约束 ~
只有在启用 TypeFamilies
或 GADTs
时才能写出。
但是,启用 TypeFamilies
或 GADTs
也会启用 MonoLocalBinds
. 顾名思义,它会禁用局部定义变量的泛化。
如果 MonoLocalBinds
阻止代码编译,您应该写出通用类型签名或将此类局部变量分解为顶级定义。有时写出泛化类型有点困难;在这种情况下,您可以尝试查询 GHCi,或者您可以启用 NoMonomorphismRestriction
,编写未注释的顶级定义,然后查看推断的类型。