Polysemy: Onion architecture
Until now we only seen "low-level" effects (either classical Monad, or technical effects).
On of my main motivation with effects systems is to be used in an Onion architecture.
Doing so, we can imagine to modelise a car return within a car rental business.
For example, last year we introduced a Cache effect:
returnCar ref observations = do
booking <- fetchBooking ref
car <- fetchCar booking.carRef
let newDamages = inducedDamages car observations
registerReturnedCar car.ref newDamages
pricedDamages <- mapM (fetchPricedDamage car.model) newDamages
return $ createBill booking car pricedDamages
with the following effects for Repositories:
data Bookings (m :: Type -> Type) a where
FetchBooking :: BookingRef -> Bookings m Booking
makeSem ''Bookings
data Cars (m :: Type -> Type) a where
FetchCar :: CarRef -> Cars m Car
RegisterReturnedCar :: CarRef -> [CarDamage] -> Cars m ()
makeSem ''Cars
data DamageReferences (m :: Type -> Type) a where
FetchPricedDamage :: () -> CarDamage -> DamageReferences m CarPricedDamage
makeSem ''DamageReferences
See the full the code here.