(Will be streamed today, 2024-07-03, 1830 UTC on YouTube.)
Thanks Andres, Edsko
Have we actually won anything? [at about 18:30]
I think your type family solution â that also needs a Proxy
for some reason â is intolerably cluttered. So no, âweâ've lost.
- Firstly, thereâs no precise specification for Overlapping instances (for
class
es â for TFs theyâre not allowed). - GHCâs behaviour is different to Hugs; and frankly I find GHCâs an unfortunate mess: you can get instances apparently accepted but unusable. And itâs more of a mess under separate compilation.
- OTOH Hugs rejects sets of instances that would be useful.
- Thereâs a proposal to address this whole topic. And you have to consider it hand-in-hand with Functional Dependencies.
So I can write this
class Add a b c | a b -> c, a c -> b, b c -> a where .. -- three FunDeps
instance Add Z b b where ... -- base case
instance Add a' b c' => Add (S a') b (S c') | b /~ (S c') -- apartness guard
where ... -- recursive case
Iâm not saying itâs universally better. I believe itâs a technique worth knowing, because sometimes it helps and unlocks new design options. But yes, it comes at a price.
It also is a technique that works right now and is applicable quite universally, as opposed to various proposals that have been made over the years to fix this problem in some other way, at least going back to Instance Chains by Garret Morris and Mark Jones in 2010, http://web.cecs.pdx.edu/~mpj/pubs/instancechains.pdf, and probably further (I recall seeing the talk about instance chains and thinking âoh, itâs another proposal to âfixâ overlapping instancesâ, but in the meantime I forgot what the previous proposals were).
Anyway, weâre not making a statement about language design in this episode. If you know the technique and decide not to use it, thatâs perfectly fine.
it doesnât, if youâre happy with -XAllowAmbigousTypes
. Whether you should is a different topic.
No Iâm not. My âintolerably clutteredâ is pondering why we need in effect to pass the same type twice to MyShow'
[at around 16:30]: once as the type-with-value [a]
that weâre showing; second as the result of applying Type Family IsString [a]
. (Then using a Proxy
is to document weâre interested in its type, not value.) We wouldnât do that in a term-level method instantiation, weâd merely call the function inside the method instance.
The justification for introducing Type Families was/is allegedly that it makes type-level coding more alike term-level coding. (Because allegedly some learners find class/instance selection/type improvement too unfamiliar.) The demo for MyShow'
is failing to demonstrate âmore alikeâ IMO.
Wellll ⌠Youâre making a statement about poor language design for Overlapping (class) Instances. And I would agree with you the state of play in GHC is awkward, particularly it too often needs constraints on instances to deliver the type improvement that it canât express in the instance head.
Prelude class Show
dates back to Haskell pre-history. It wouldnât have used Overlapping Instances back then; so the showList
trick is quite cunning. But these days why object to:
instance {- OVERLAPPING -} MyShow [Char] where ...
instance {- OVERLAPS -} MyShow [a] where ...
instance {- OVERLAPPABLE -} MyShow a where ...
I donât object to this. Itâs fine.
These videos are awesome. I learn a lot, thanks for your effort making them. Looking forward to the next episode.