I think your last eval :: Expr unsafeFlag -> Maybe Double definition is missing a TFlag unsafeFlag constraint (since it calls whenFlag :: TFlag a => ...).
Indeed, thanks for notifying me, I just corrected it ![]()
Great article! The last eval function that returns Maybe Double should have liftA2 (+) (eval x) (eval y), no?
You’re right! Corrected ![]()
Why is TFlag needed as a class?
This HKD: best or worst thing ever? - #7 by rhendric extends on the use of Void/() for cardinality
I should have guessed that people had thought of this before me x) (to be honest, I did, I just didn’t realize that kind of thing was a common pattern).
Regarding the type class, that’s the solution I came up with to write functions such as the post’s eval, that is, functions that consume types with a generic type flag. There may be another way, I’m which case I’m happy to hear about it ![]()
Reminds me of Trees That Grow: trees that grow guidance · Wiki · Glasgow Haskell Compiler / GHC · GitLab
But your blog post provides a good intuition and introduction to the idea!
Yes people have mentioned it elsewhere too, but I didn’t get the chance to get into it yet! Might do a nice follow-up post maybe? Anyway thanks for the link, all I found was the paper, having stuff written out more in a programming oriented style as well should help ![]()
In the definition of data Expr unsafeFlag it seems as though you’re missing the unsafeFlag in each of the Expr parameters of Div. Or am I mistaken and you are referring to the first data Expr at the top of the post?
You’re not mistaken, it’s astonishing how many oversights one can pack in such a small post. I’ll update it when I get the chance, thanks for the heads up.
I believe that if you make the field that can contain Void strict, you don’t have to include a case for it when you know that it’s Void.
You can also do something similar to what you have here with a GADT, but your implementation doesn’t need GADTs which is nice.
eval (Div w x y) = whenFlag w $
if eval y == Just 0.0
then Nothing
else (/) <$> eval x <*> eval y
whenFlag returns an f (), eval returns a Maybe Double. It’s why I don’t understand TFlag, as that is your only use of it. Also, another definition of TFlag is this. class TFlag a where getRefl :: a -> Refl a (). See Leibniz equality in Haskell, part 1 - Ryan Scott.
Wait you’re totally right, my code still doesn’t compile, and this time the issue is pretty fundamental… I’m very embarrassed to have published such a flawed blog post. It is salvageable, though, I’ll update it ASAP. Thanks for pointing out the issue.