<div dir="ltr">Hi Vlatko,<br><br>Did you consider:<br><br>{-# LANGUAGE RankNTypes #-}<br>data ThingCfg m = ThingCfg {<br>    thingDb  :: Text,<br>    thingRun_ :: forall a. Text -> m a -> IO a }<br><br>thingRun (ThingCfg db f) = f db<br>

<br>Maybe the `m' above should be SqlPersistM, if all your other backends use that type.<br><br>--<br>Adam<br></div><div class="gmail_extra"><br><br><div class="gmail_quote">On Tue, Jan 28, 2014 at 1:37 PM, Vlatko Basic <span dir="ltr"><<a href="mailto:vlatko.basic@gmail.com" target="_blank">vlatko.basic@gmail.com</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Hello Cafe,<br>
<br>
I'm playing with Persistent and have modules that I'd like to use on several backends. This is simplified situation.<br>
<br>
In shared module:<br>
<br>
  sqliteRun, postgresRun :: Text -> Int -> (ConnectionPool -> IO a) -> IO a<br>
  sqliteRun          = withSqlitePool<br>
  postgresRun conStr = withPostgresqlPool (encodeUtf8 conStr)<br>
<br>
  sqlRun :: Text -> Int -> SqlPersistM a -> IO a<br>
  sqlRun conStr poolSize = postgresRun conStr poolSize . runSqlPersistMPool<br>
  --sqlRun conStr poolSize = sqliteRun conStr poolSize . runSqlPersistMPool<br>
        <br>
All works well if either 'sqlRun' above is commented/uncommented:<br>
<br>
<br>
In one of modules:<br>
<br>
  data ThingCfg = ThingCfg { thingDb :: Text }<br>
<br>
  listThings :: ThingCfg -> IO [Thing]<br>
  listThings db = sqlRun (thingDb db) $ selectList ...<br>
        <br>
  findThing :: ThingId -> ThingCfg -> IO (Maybe Thing)<br>
  findThing uid db = sqlRun (thingDb db) $ getBy ...<br>
<br>
<br>
<br>
On call site simply:<br>
  let tdb = ThingCfg "test"<br>
  ts <- listThings tdb<br>
<br>
<br>
I would like to specify 'sqliteRun' or 'postgresRun' function as (some) parameter on the call site, but do not know how.<br>
Something of imaginary solution:<br>
<br>
  data ThingCfg = ThingCfg {<br>
      thingDb  :: Text,<br>
      thingRun :: SqlPersistM a -> IO a<br>
    }<br>
<br>
On call site:<br>
  let tdb = ThingCfg "test" sqliteRun<br>
  ts <- listThings tdb<br>
<br>
I want to keep it as an init param because there are other backends (class instances) that are not Persistent, so the use of 'sqlRun' on call site is not an option.<br>
<br>
<br>
What would be the best/correct way(s) to achieve that?<br>
<br>
<br>
Best regards,<br>
  Vlatko<br>
______________________________<u></u>_________________<br>
Haskell-Cafe mailing list<br>
<a href="mailto:Haskell-Cafe@haskell.org" target="_blank">Haskell-Cafe@haskell.org</a><br>
<a href="http://www.haskell.org/mailman/listinfo/haskell-cafe" target="_blank">http://www.haskell.org/<u></u>mailman/listinfo/haskell-cafe</a><br>
</blockquote></div><br></div>