Polysemy Clean Architecture - Polysemy

Welcome to the Functional Programming Zulip Chat Archive. You can join the chat here.

Rizary

While I am searching on how to structure my project using Polysemy, I came accross this https://github.com/thma/PolysemyCleanArchitecture. Despite the clean code founder (which is Robert C. Martin), I found interest in pursuing what describe in this repo. Anyone has thought on this?

I haven't seen production-grade app which use Polysemy in anger. If anyone has an answer, please let me know.

Showcasing how the Polysemy library can be used to implement a REST application conforming to the guidelines of the Clean Architecture model. - thma/PolysemyCleanArchitecture
Georgi Lyubenov // googleson78

one of the big differences between this and something more "real-world" is that you need more granular actions for your db

Georgi Lyubenov // googleson78

getting all the values and filtering in haskell obviously doesn't scale very well

Georgi Lyubenov // googleson78

you probably also want transactions as an effect, because otherwise you can't compose two db actions within the same transaction

Georgi Lyubenov // googleson78

(or you could do something more "heavy handed" like running all your actions for one query inside the same transaction I guess)

Rizary

Georgi Lyubenov // googleson78 said:

you probably also want transactions as an effect, because otherwise you can't compose two db actions within the same transaction

I just want to clarify, do you mean by transaction as an effect, is wrt this code? https://github.com/thma/PolysemyCleanArchitecture/blob/master/src/UseCases/ReservationUseCase.hs ?

or the reservation in here: https://github.com/thma/PolysemyCleanArchitecture/blob/master/src/Domain/ReservationDomain.hs?

Showcasing how the Polysemy library can be used to implement a REST application conforming to the guidelines of the Clean Architecture model. - thma/PolysemyCleanArchitecture
Showcasing how the Polysemy library can be used to implement a REST application conforming to the guidelines of the Clean Architecture model. - thma/PolysemyCleanArchitecture
Rizary

oh god, how do we remove thumbnail.. in discord I can just use <link>format

Georgi Lyubenov // googleson78

I'm still not sure if you can, after posting a message! unfortunately..

Georgi Lyubenov // googleson78

yep, I'm referring to the fact that if you call two KVS actions one after another, as it is implemented right now in the repo, they won't run in the same transaction
(if you use runKvsAsSQLite)

Georgi Lyubenov // googleson78

so unless you have some mechanism to express when you want to start and end a transaction in your "business logic" you will always have to "hardcode" when transactions start and end

Rizary

Georgi Lyubenov // googleson78 said:

yep, I'm referring to the fact that if you call two KVS actions one after another, as it is implemented right now in the repo, they won't run in the same transaction
(if you use runKvsAsSQLite)

hmm I'm still confused (maybe because I don't have enough knowledge on Polysemy). After I search more, I found this repo (which I'm stealing some code from) https://github.com/fendor/ase-ss20-slacker-team/blob/master/src/Postgres/Polysemy.hs that maybe close to what you mean.

But then I wonder if I need to interpret twice? If from the following code, the getAction k is another effect. How do I do that?

runKvsAsSQLite = interpret $ \case
  GetKvs k      -> getAction k
  ListAllKvs    -> listAction
  InsertKvs k v -> insertAction k v
  DeleteKvs k   -> deleteAction k
Contribute to fendor/ase-ss20-slacker-team development by creating an account on GitHub.
Georgi Lyubenov // googleson78

What I mean is the following:
Your linked repo works like this
Effects:

  • Database actions
    • get
    • delete
    • insert

Effect interpreters work like this:
get - start transaction, get data, end transaction
delete - start transaction, delete data, end transaction
insert - start transaction, insert data, end transaction

so if you write

xKey <- insert <data>
<data> <- get xKey

the insert and the get will run in different transactions, meaning that the <data> might already be gone or modified by the time you're geting it

instead you want some way to do

Effects:

  • Transaction:

    • transaction <other database actions>
  • Database actions

    • get
    • insert
    • delete

And your interpreters will do something like:
transaction mx - start transaction, run the mx action, end transaction

so that you can now write

transaction $ do
  xKey <- insert <data>
  <data> <- get xKey

and be sure that your data is consistent
there were discussions and proposed solutions for this - https://github.com/polysemy-research/polysemy/issues/361#issuecomment-702344580, and https://funprog.srid.ca/polysemy/interpreter-for-action-that-adds-on-the-effect-stack.html#212801533
(the second one is better)

Hi, I've been pulling my hair for the last couple of days on this issue, but I can't manage to find a solution, I would appreciate if anyone can help me! Goal Use together Polysemy and Pers...
how can I implement runTransaction? data Db m a where -- ... data Token runDb :: Member (Embed IO) r => Token -> Sem (Db ': r) a -> Sem r a runDb tok = interpret \case data Transaction m a where InTransaction :: Sem (Db ': r) a -> Transaction (Sem r) a inTransaction :: Member Transaction r =
Rizary

Thank you, so it's been discussed previously. I should search it before. I'll read that link. Thanks.

Rizary

After reading the link and trying to implement the solutions, I think I am gonna use with the current non-"real world" app approach. It's a small playground to implement polysemy though.

Maybe after I learned more about effect system, I'll get back to it.