2014-05-02 18 views
5

Qual è l'istanza corretta per il ritorno di runDB dopo aver caricato un sito scaffold in ghci? Ad esempio, durante l'esecuzione di questa frase:Yesod: digitare l'errore di istanza durante l'esecuzione della funzione `runDB` in ghci

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

l'errore è:

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"] [] 

Grazie in anticipo

Edit: ho dimenticato di Yesod Ponteggio runDB restituisce un Handler, che mi ha portato a questa soluzione alternativa (anche se sono sicuro che sia una soluzione migliore):

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

dove "MyProject.sqlite3" è il nome del database Sqlite.

Questa non è una soluzione generalizzata. Secondo la documentazione e come dice questo post, varia leggermente per altri backend.

+0

Cosa succede se si disattiva [restrizione monomorfismo] (http://www.haskell.org/haskellwiki/Monomorphism_restriction) con ': set -XNoMonomorphismRestriction'? – bheklilr

+0

Questa è una buona domanda. Non avevo nemmeno pensato di usare GHCi come front end a persistente. – nomen

+0

@nomen ringrazia per la risposta. Penso di aver trovato una soluzione (vedi l'ultima versione modificata della domanda). Ciao – renny

risposta

3

Il problema è che, a differenza delle lingue imperative che si basano sullo stato dell'ambiente, Haskell si basa sul passaggio di stato esplicito (e implicito).

Quando si esegue runDB $ ... da ghci, si sta tentando di eseguire questo snippet direttamente all'interno di IO e quindi non si ha alcun riferimento allo stato dell'applicazione (che include la connessione al database). L'errore di tipo ti informa che è The type variable 'site0' is ambiguous perché non può dedurre quale stato dell'applicazione stai cercando di eseguire questa dichiarazione.

All'interno di ghci, il prefisso runSqlite "MyProject.sqlite3" funziona perché si sta impostando specificamente l'ambiente per l'esecuzione sul database corretto e runSqlite funziona in IO, che è ciò che Ghci vuole.