I'm trying to figure out the differences between type classes and GADTS, especially when using -XMultiParamTypeClasses
extension.
Both appear to have similar uses:
class MyClass a b where
f :: a -> b -> Bool
instance MyClass String String where
f s1 s2 = ...
instance MyClass Int Int where
f i1 i2 = ...
data Gadt a where
F :: String -> String -> Bool
F2 :: Int -> Int -> Bool
So far, the only difference I really see is that GADT's enable a function type interface to have a flexible number arguments:
data Gadt a where
PassTwoArgs :: String -> String -> Gadt Bool
PassOneArgs :: String -> Gadt Bool
myFunction :: Gadt a -> a
myFunction (PassTwoArgs s1 s2) = ...
myFunction (PassOneArgs s1) = ...
Whilst this isn't easily done with type classes.
Are there any other differences or use cases to use one over the other?
If you have a class, you can add new instances at any time.
If you use a GADT, you have a data structure which is fixed forever. You can never add new cases to it, without altering the original definition. However, as you note, it's far more flexible.
Really, they're intended for different use-cases. Classes are for when you want to be able to do a thing to lots of different data types which otherwise have nothing to do with each other. (E.g., you can do (==)
on Int
and on String
, but those types aren't very similar.) GADTs are for when you want to have one type, but some of its type parameters tell you something about it. The canonical example is where the GADT represents an expression in some programming language, and you want to use the Haskell type system to enforce the other language's type system.
What classes are not like are the "classes" we use in object-oriented programming. ;-) Please put all such ideas out of your brain.
If you need pattern matching, use a (G)ADT. If you need third parties to be able to implement your interface, use a typeclass.
My intuition is to use typeclasses as much as possible; if I absolutely need pattern matching, then I'll reach for a (G)ADT. I usually don't need it.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With