I have a class HasFavorite
which assigns certain domains with my corresponding favorites.
class HasFavorite domain where
favorite :: domain
data Animal = Monkey | Donkey
deriving Show
data Color = Red | Blue
deriving Show
instance HasFavorite Animal where
favorite = Donkey
instance HasFavorite Color where
favorite = Blue
Now, I want to define this:
rant :: (Show d, HasFavorite d) => d -> String
rant x = (show x) "sucks. " (show (favorite :: d)) " is better."
For every invocation of rant x
there is a concrete type to which favorite :: d
can be resolved. Why can't Haskell do this?
I have tried adding {-# LANGUAGE ScopedTypeVariables #-}
but that did not help.
CodePudding user response:
In addition to ScopedTypeVariables
, you also need to add a forall d
to the type signature of rant
:
rant :: forall d. (Show d, HasFavorite d) => d -> String
rant x = (show x) " sucks. " (show (favorite :: d)) " is better."
Or you could match on the argument type:
rant :: (Show d, HasFavorite d) => d -> String
rant (x :: d) = (show x) " sucks. " (show (favorite :: d)) " is better."
See the GHC manual for all the details.