What is the FlexibleContexts extension good for? Could you please explain it using a simple example?
Without FlexibleContexts
all typeclass constraints on function definitions must have type variables. For example:
add :: Num a => a -> a -> a
add = (+)
Where a
is the type variable. With FlexibleContexts
enabled you can have any type inside a typeclass.
intAdd :: Num Int => Int -> Int -> Int
intAdd = (+)
This example is pretty contrived but it is the simplest I can think of. FlexibleContexts
is usually only used with MultiParamTypeClasses
. Here is an example:
class Shower a b where
myShow :: a -> b
doSomething :: Shower a String => a -> String
doSomething = myShow
Here you can see we say that we only want a Shower a String
. Without FlexibleContexts
String
would have to be a type variable instead of a concrete type.
Commonly it's used with the MultiParamTypeClasses
extension, for example when using the mtl
library you might write
doSomethingWithState :: MonadState MyState m => m ()
doSomethingWithState = do
current <- get
let something1 = computeSomething1 current
something2 = computeSomething2 current something1
put something2
And similarly with MonadReader
and MonadWriter
, along with other similar typeclasses. Without FlexibleContexts
you can't use this constraint.
(Note that this answer was based on @DiegoNolan's but rewritten to use an existing library that should make sense to LYAH readers).
I've discovered a use for it apart from those mentioned: it results in clearer error messages from GHC. E.g. normally,
Prelude> max (1, 2) 3
<interactive>:1:1: error:
• Non type-variable argument in the constraint: Num (a, b)
(Use FlexibleContexts to permit this)
• When checking the inferred type
it :: forall a b.
(Num (a, b), Num b, Num a, Ord b, Ord a) =>
(a, b)
And with FlexibleContexts enabled:
Prelude> max (1, 2) 3
<interactive>:1:1: error:
• No instance for (Num (Integer, Integer))
arising from a use of ‘it’
• In the first argument of ‘print’, namely ‘it’
In a stmt of an interactive GHCi command: print it
Here's a discussion.