Different advice for type classes for end-user app and libraries?

Hello list! Currently I am working a end user application. Through the years I had incorporated the advice from r/haskell that classes without laws were not desirable. Their lack meant that we didn't have a contract boundary that should be respected by the instances. They secretly could `throw exc` on their implementation and you wouldn't notice. But on the current app I am working on, I follow the advice from this blogpost [1] that I should use classes for domain modelling. This manifest on classes like class UserQueryCapability f where getUser :: Id -> f User for interacting with a DB. Functions can be written against the interface and I can mock up with QuickCheck some pretty broad cases. The classes usually don't have a superclass constrain on `Monad` as in `MonadReader` because I *cannot* establish a law relating the monadic behavior and `getUser`. The name has Capability in it and not Monad because I won't lie that way. Making sure that these effect classes are orthogonal is something I have to check by hand. But in the back of my head there is the concern about the lack of laws could bite me even on a end user-app. Is my intuition well founded that this case is OK? Thanks for your time! [1]: https://www.parsonsmatt.org/2018/03/22/three_layer_haskell_cake.html -- -- Rubén. pgp: 4EE9 28F7 932E F4AD

You're using classes in the context of MTL in an effect system-ish fashion, which is not *quite* what was the original intent and wisdom of Typeclasses in Haskell. Here Typeclasses are being used to implement a query interface, which is not the most "natural" usage of ad-hoc polymorphism. As such, I wouldn't expect such typeclasses to fully comply to the customs of Typeclasses. Don't worry too much about it. You're already playing outside of the customary bounds for Typeclasses. :) Le 12/08/2021 à 17:41, Ruben Astudillo a écrit :
Hello list!
Currently I am working a end user application. Through the years I had incorporated the advice from r/haskell that classes without laws were not desirable. Their lack meant that we didn't have a contract boundary that should be respected by the instances. They secretly could `throw exc` on their implementation and you wouldn't notice.
But on the current app I am working on, I follow the advice from this blogpost [1] that I should use classes for domain modelling. This manifest on classes like
class UserQueryCapability f where getUser :: Id -> f User
for interacting with a DB. Functions can be written against the interface and I can mock up with QuickCheck some pretty broad cases. The classes usually don't have a superclass constrain on `Monad` as in `MonadReader` because I *cannot* establish a law relating the monadic behavior and `getUser`. The name has Capability in it and not Monad because I won't lie that way.
Making sure that these effect classes are orthogonal is something I have to check by hand. But in the back of my head there is the concern about the lack of laws could bite me even on a end user-app. Is my intuition well founded that this case is OK?
Thanks for your time!
[1]: https://www.parsonsmatt.org/2018/03/22/three_layer_haskell_cake.html
-- Hécate ✨ 🐦: @TechnoEmpress IRC: Hecate WWW: https://glitchbra.in RUN: BSD
participants (2)
-
Hécate
-
Ruben Astudillo