Desugaring Haskell Syntax to type classes seems to have become the norm. While this is powerful, it also has a number of limitations, e.g.
- type classes have to be globally coherent
- GHC sometimes cannot guess your intentions (ambiguous types errors)
- type classes constrain your implementation (e.g.
IsList
)
I think that -XQualifiedDo
is a great extension to show a middle way on the spectrum between -XRebindableSyntax
and globally coherent desugaring to type classes and I think we should build on this; the idea: -XQualifiedSyntax
which makes haskell syntax qualifyable. Examples:
-- Data.Vector and Data.Monoid implement fromList
import Data.Vector qualified as Vec
import Data.Monoid qualified as Monoid
-- Data.ByteString implements fromString
import Data.ByteString qualified as BS
-- Data.Int implements fromIntegral
import Data.Int qualified as Int
-- I have a weird eDSL where it makes sense to represent
-- bits as Bools but I don't want to make sure the user
-- is aware when using this partial syntax + I don't want the
-- definition that is intended only for syntax to be infective
import MyModule.Bits qualified as Bits
-- I'm super into singletons and want to have a version of `if then else` that
-- works with type level booleans
import Data.SBool qualified as S
import Data.SOP.NP qualified as NP
x = V.[Int.1, 2, 3]
y = Monoid.[BS."hello", "world"]
z :: Bool
z = and Bits.101001
a b = S.if b then "hello" else 42
x :: NP I [Int, Bool, String
x = NP.[3, I False, "what"]
A non-exhaustive list of syntax this would effect
- numeral syntax (fromInteger, fromRational)
- string syntax
- list syntax
- negate
- conditionals (
if then else
) -
do
(everything included into-XQualifiedDo
today - arrow syntax
- overloaded labels
More patholical syntaxes:
- overloaded record dot
- overloaded record update (I’m not sure about this actually, maybe it’s fine)
What do you think about this?