[Takusen] Nested Iterations with Takusen

Jason Dagit dagitj at gmail.com
Tue Apr 19 05:08:59 BST 2011


On Mon, Apr 18, 2011 at 10:39 AM, Pepe Barbe <elventear at gmail.com> wrote:

> Hello everyone,
>
> I am new to Haskell and I am trying to use the Takusen library to query an
> SQL database. My desire is two perform a two level query query where the
> first query will iterate through some values  that will be used in the
> second level to get the data of interest.
>
> I am having issues with the types and I haven't been able to figure out
> what am I doing wrong. Below is some sample code that shows the problem I am
> dealing with:
>
> -- sample.hs
> import Database.PostgreSQL.Enumerator
> import Database.Enumerator
>
> db_host        = CAhost "host"
> db_user        = CAuser "user"
> db_password    = CApassword "pass"
> db_name        = CAdbname "name"
> db_auth_tokens = [db_user, db_password, db_host, db_name]
> connection     = connect db_auth_tokens
>
> secondLevelQuery :: IO Integer
> secondLevelQuery = do
>  let query = sql "SELECT count(*) from alarms"
>     iter :: Monad m => Integer -> IterAct m Integer
>     iter count _ = result' count
>  withSession connection (doQuery query iter 0)
>
> firstLevelQuery :: IO (Integer, Integer)
> firstLevelQuery = do
>  let query = sql "SELECT count(*) from alarms"
>     iter :: Monad m => Integer -> IterAct m (Integer, Integer)
>     iter count _ = do
>                   count' <- secondLevelQuery
>                   result' (count', count)
>  withSession connection (doQuery query iter (0,0))
>
> main = firstLevelQuery
> -- end sample.hs
>
> And the output from ghc is:
>
> sample.hs:23:31:
>   Could not deduce (m ~ IO)
>   from the context (Monad m)
>     bound by the type signature for
>                iter :: Monad m => Integer -> IterAct m (Integer, Integer)
>     at sample.hs:(22,7)-(24,43)
>     `m' is a rigid type variable bound by
>         the type signature for
>           iter :: Monad m => Integer -> IterAct m (Integer, Integer)
>         at sample.hs:22:7
>   Expected type: m Integer
>     Actual type: IO Integer
>   In a stmt of a 'do' expression: count' <- secondLevelQuery
>   In the expression:
>     do { count' <- secondLevelQuery;
>          result' (count', count) }
>   In an equation for `iter':
>       iter count _
>         = do { count' <- secondLevelQuery;
>                result' (count', count) }
>
> I would appreciate any help in figuring out what am I doing wrong.
>

I think I see the problem, but I haven't tried to compile your code so I
could be missing something.

I think what GHC is trying to say is that you've declared something to work
for all Monads m, but you're also requiring it to work for IO.  In
particular, using withSession inside secondLevelQuery forces
secondLevelQuery to use the IO monad.

So then in firstLevelQuery, this line:
count' <- secondLevelQuery

Forces iter to only work for the IO monad.  GHC is complaining because iter
was declared to work for all monads but the way it's implemented forces it
to only work for the IO monad.

If you change it to:
iter :: Integer -> IterAct IO (Integer, Integer)

Does your type error go away?

I hope that helps,
Jason
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://projects.haskell.org/pipermail/takusen/attachments/20110418/ab7737c8/attachment.htm>


More information about the Takusen mailing list