2015-04-08 45 views
6

Mam moduł zakodowany i działający, ale nie mogę do niego wprowadzić dwóch podpisów funkcji, ponieważ aby je wprowadzić, muszę włączyć rozszerzenie TypeFamilies dla modułu, a kiedy zrób to, już nie buduje.włączenie TypeFamilies sprawia, że ​​kod nie jest już budowany

Dla jednego z nich potrzebuję TypeFamilies, ponieważ używa się persisent/esqueleto functions.

odpowiedniego typu byłoby, wierzę:

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

(ghc proponuje bardziej ogólny podpis)

Drugi wykorzystuje hsqml.

ghc sugeruje ten podpis, ale myślę, że to może być uproszczone:

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

Najważniejsze jest to, że bez TypeFamilies nie mogę pisać te podpisy. Jednak w momencie, gdy włączę TypeFamilies, kod nie będzie budowany i nie rozumiem dlaczego. Błąd wygląda na to, że niektóre funkcje polimorficzne nagle stały się monomorficzne.

Wynik błędu jest stosunkowo długi, można go znaleźć here.

mam TypeFamilies włączona w kilku innych modułów aplikacji bez problemów, a to pozwala mi pisać podpisy za pomocą zarówno SqlBackend & ICanReturnTo ograniczeń bez problemów.

Czy coś jest nie tak z tym modułem, który uniemożliwia jego budowanie z TypeFamilies? Czy powinienem włączyć jeszcze jedno rozszerzenie, żeby to naprawić? Nie spodziewałem się po prostu włączenia tego rozszerzenia, aby przerwać kompilację.

+0

Co jest nie tak z ogólnym typem GHC? Jeśli działa na GHC, to powinna się skompilować dobrze. – AJFarmar

Odpowiedz

9

Ograniczenie równości typu ~ można zapisać tylko wtedy, gdy włączone jest TypeFamilies lub GADTs.

Jednak włączenie TypeFamilies lub GADTs również umożliwia MonoLocalBinds. Jak sama nazwa wskazuje, wyłącza generalizację lokalnych zdefiniowanych zmiennych.

Jeśli MonoLocalBinds uniemożliwia skompilowanie kodu, należy wypisać uogólnione podpisy typów lub wyodrębnić takie locale w definicje najwyższego poziomu. Czasami pisanie uogólnionych typów jest nieco trudne; w takich przypadkach możesz spróbować wysłać zapytanie do GHCi lub włączyć NoMonomorphismRestriction, napisać niezalogowane definicje najwyższego poziomu, a następnie spojrzeć na typy wywnioskowane.

+3

'NoMonoLocalBinds' rzeczywiście sprawia, że ​​jest on budowany. Nie znałem tego. W tej chwili nie rozumiem różnicy między tym a "NoMonomorphismRestriction" chociaż wydaje się, że są prawie takie same. W każdym razie wiem, gdzie szukać teraz dziękuję! –

+0

Całkowicie zapomniałem, że jest też flaga 'NoMonoLocalBinds'. –

+1

Tak, ale https://downloads.haskell.org/~ghc/latest/docs/html/users_guide/other-type-extensions.html#mono-local-binds mówi "Możesz wyłączyć to ponownie za pomocą' -XNoMonoLocalBinds' ale wnioskowanie typu staje się mniej przewidywalne, jeśli to zrobisz (przeczytaj artykuły!) "- dlatego wolę adnotować zmienne lokalne zgodnie z sugestiami. –