[Haskell-cafe] Re: Foralls in records

apfelmus at quantentunnel.de apfelmus at quantentunnel.de
Wed Mar 14 12:26:57 EDT 2007


Adde wrote:
>> Do you want to mix differently typed Connections inside a single
>> transaction? It looks like you don't, so you may well leave out
>> existential types altogether and simply parametrize the Transaction
>> monad on the type of the connection it uses.
>>
>>   data Connection c => TransactionState c = TS c
>>   data Transaction c a =
>>      Transaction (TransactionState c -> (a, TransactionState c)
>>
>>   instance Monad (Transaction c) where ...
>>
>>   getConnection :: Transaction c c
>>   ...
>>
>> Note that Control.Monad.State does the same.
> 
> You are correct in that I don't want to mix different kind of connections 
> inside a single transaction. I just didn't want to have to parameterize every 
> single function using the monad.
> 
> doSomething :: Transaction FirebirdConnection ()
> 
> doSomethingElse :: Transaction FirebirdConnection ()
> 
> Maybe I'm misunderstanding something but as I see it that would kind of stop 
> me from running doSomething and doSomethingElse using different kinds of 
> databases.

Your monadic action may well be polymorphic in the state type:

  doSomething     :: Connection c => Transaction c ()
  doSomethingElse :: Connection c => Transaction c ()

thus working for all databases. In case your function really depends on
a particular database vendor, you have the possibility to annotate this
in the connection type:

  doSomethingThatOnlyWorksForFirebird :: Transaction Firebird ()


The additional 'Connection c' constraint in the first examples may be a
bit unwieldy. But I guess that you can drop when redesigning your monad.
After all, I'm unsure what you intend 'Transaction' to do. Wouldn't

   runTransaction :: Transaction c a -> IO a

be a function you need? Shouldn't things of the Transaction monad be
completely back end independent so that you can drop the parameter c
altogether? Why do you intend 'Transaction' to be a state monad, I mean
why is the only thing you can do with the state something of type (c ->
String -> IO ())? Btw, this has been (c -> String -> Transaction ()) in
your original post.

Regards,
apfelmus



More information about the Haskell-Cafe mailing list