[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