I’m modelling a round robin scheduler in Haskell.
class Schedulable s where
isFinal :: s -> Bool
class Scheduler s where
add :: (Schedulable a) => a -> s -> s
next :: (Schedulable a) => s -> (a, s)
empty :: s -> Bool
data Schedulable a => RoundRobin = RoundRobin [a] [a]
instance Scheduler RoundRobin where
add p (RoundRobin ps qs) = RoundRobin (ps ++ [p]) qs
next (RoundRobin [] qs) = next (RoundRobin qs [])
next (RoundRobin (p:ps) qs) = (p, RoundRobin ps (qs ++ [p]))
empty (RoundRobin [] _) = True
empty _ = False
However, GHC complains that
main.hs:9:6:
Illegal datatype context (use -XDatatypeContexts): Schedulable a =>
How can I solve this issue?
I also saw a proposal about removing datatype contexts, so how can I model the scheduler without using datatype contexts?
Your
Schedulerclassis not going to work.
addpromises that values of anySchedulabletype can be added to the scheduler. That is possible, but it requires an extension,ExistentialQuantificationorGADTswould allow to define a type wrapping anySchedulablevalue.next, however, promises to deliver a value of anySchedulabletype, whatever the caller desires, and that’s not going to work. If I only ever addIntvalues to the scheduler, and then ask for aString, how would it construct one out of thin air?One way to get your code to work is
Using
GADTsyntax or existential quantification makes the constraints imposed on the constructor available via pattern matching, in contrast to the oldDatatypeContextsthat despite the constraints on the type, required the context put on the functions using the type.