Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Yesod: Type instance error while running `runDB` function in ghci

What is the correct instance to get the runDB return after loading a scaffolded site in ghci? For example, while running this sentence:

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

the error is:

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

Thanks in advance

Edit: I forgot Yesod Scaffold's runDB returns a Handler, which led me to this workaround (though I'm sure it is a better solution):

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

where "MyProject.sqlite3" is the name of Sqlite database.

This is not a generalized solution. According to the documentation and as this post says, it slightly varies for other backends.

like image 827
renny Avatar asked Oct 21 '22 09:10

renny


1 Answers

The problem is that unlike imperative languages which rely on ambient state, Haskell relies on explicit (and implicit) state passing.

When running runDB $ ... from ghci, you are trying to run this snippet directly within IO, and hence you have no reference to your application state (which includes your database connection). The type error is informing you that it The type variable 'site0' is ambiguous because it cannot infer what application state you are trying to run this statement against.

Within ghci, prefixing runSqlite "MyProject.sqlite3" works because you are specifically setting up the envirionment to run against the correct database, and runSqlite works in IO, which is what ghci wants.

like image 148
Thomas Avatar answered Oct 22 '22 23:10

Thomas