2014-05-02 8 views
5

Jaka jest poprawna instancja, aby uzyskać powrót do runDB po załadowaniu strony z rusztowaniem w ghci? Na przykład, podczas pracy to zdanie:Yesod: Wpisz błąd wystąpienia podczas działania funkcji `runDB` w ghci

runDB $ selectList [UserName ==. "Renny"] [] 

błędu jest:

Couldn't match type `PersistMonadBackend 
(YesodPersistBackend site0 (HandlerT site0 IO))' 
with `persistent-1.3.0.6:Database.Persist.Sql.Types.SqlBackend' 
The type variable `site0' is ambiguous 
Possible fix: add a type signature that fixes these type variable(s) 
Expected type: PersistMonadBackend 
       (YesodPersistBackend site0 (HandlerT site0 IO)) 
    Actual type: PersistEntityBackend User 
In the second argument of `($)', namely 
    `selectList [UserName ==. "Renny"] []' 
In the expression: runDB $ selectList [UserName ==. "Renny"] [] 
In an equation for `it': 
    it = runDB $ selectList [UserName ==. "Renny"] [] 

góry dzięki

Edit: zapomniałem Jesod rusztowań na runDB zwraca Handler, która doprowadziła mnie do tego obejście (choć jestem pewien, że jest to lepsze rozwiązanie):

xs <- runSqlite "MyProject.sqlite3" (selectList [UserName ==. "Renny"] []) 

gdzie "MyProject.sqlite3" to nazwa bazy danych Sqlite.

To nie jest ogólne rozwiązanie. Zgodnie z dokumentacją i, jak podaje to post, różni się nieco w przypadku innych backendów.

+0

Co się stanie, jeśli wyłączysz [ograniczenie monomorfizmu] (http://www.haskell.org/haskellwiki/Monomorphism_restriction) za pomocą ': set -XNoMonomorphismRestriction'? – bheklilr

+0

To dobre pytanie. Nie myślałem nawet o tym, żeby używać GHCi jako przedniej końcówki do wytrwałości. – nomen

+0

@Nomen dzięki za odpowiedź. Myślę, że znalazłem jedno rozwiązanie (zapoznaj się z ostatnio edytowaną wersją pytania). PA – renny

Odpowiedz

3

Problem polega na tym, że w przeciwieństwie do języków imperatywnych, które opierają się na stanie otoczenia, Haskell polega na jawnym (i niejawnym) przekazywaniu stanu.

Po uruchomieniu runDB $ ... z ghci, próbujesz uruchomić ten fragment bezpośrednio w IO, a więc nie masz żadnego odniesienia do stanu aplikacji (która obejmuje połączenie z bazą danych). Błąd typu informuje Cię, że jest to The type variable 'site0' is ambiguous, ponieważ nie może wywnioskować, do jakiego stanu aplikacji próbujesz uruchomić tę instrukcję.

W ghci prefiks runSqlite "MyProject.sqlite3" działa, ponieważ specjalnie ustawiasz środowisko, aby działało na poprawną bazę danych, a runSqlite działa w IO, co jest tym, czego chce ghci.

Powiązane problemy