3 ms·
There are a few other differences as well. I'm not completely familiar with the ins and outs of Java interfaces, but: * You can instantiate types to classe
by tel 13y ago
There are a few other differences as well. I'm not completely familiar with the ins and outs of Java interfaces, but:
* You can instantiate types to classes at any point in
time (type definition, class definition, or even orphan
instances, though that last category is frowned upon)
* Typeclasses indicate typing bounds but do not destroy
type information. This means that we can define
things like
showableId :: Show a => a -> a
showableId x = x
which allow only showable types to pass but does not
destroy type information
> showableId (3 :: Int)
3 :: Int
> showableId (id :: Int -> Int)
!! Type error
* Typeclasses can dispatch on *any* type in the signature.
This includes the famous "return type polymorphism" but
generally means that typeclass resolution involves
solving a terminating form of Prolog during
typechecking. This means that type information flows
forward and backward over judgements and allows for
greater inference.
* Typeclasses can abstract over higher kinded types. So we
can write something like
count :: Traversable t => t a -> Int
count = getSum
. getConst
. traverse (const $ Const (Sum 1))
which generically counts the elements in any container
instantiating the "interface" Traversable.
There's also some even funkier techniques you can use when you start involving MultiParamTypeClasses, FunctionalDependencies, or TypeFamilies.