As a continuation of my previous question Using makeLenses, class restrictions, and type synonyms together I have a new type error that I would like to understand.
A type error is caused by the introduction of a type synonym of type S = (Num n) => State n in the example below.
{-# LANGUAGE TemplateHaskell #-} {-# LANGUAGE RankNTypes #-} module Foo where import Control.Lens data State a = State { _a :: a } deriving Show makeLenses ''State -- Requires TemplateHaskell -- | Smart constructor enforcing class constraint on record field _a. mkState :: (Num a) => a -> State a mkState n = State {_a = n} doStuff1 :: Num a => State a -> State a doStuff1 s = s & a %~ (*2) test1a = doStuff1 $ mkState 5 -- results in State {_a = 10.0} test1b = doStuff1 $ mkState 5.5 -- results in State {_a = 11.0} type S = (Num n) => State n -- Requires the RankNTypes extensions doStuff2 :: S -> S doStuff2 s = s & a %~ (*2) test2a = doStuff2 $ mkState 5 -- Results in State {_a = 10.0} --test2b = doStuff2 $ mkState 5.5 -- Type error.
If I uncomment test2b , I get the following error.
Could not deduce (Fractional n) arising from the literal `5.5' from the context (Num n) bound by a type expected by the context: Num n => State n at Foo.hs:32:10-32 Possible fix: add (Fractional n) to the context of a type expected by the context: Num n => State n In the first argument of `mkState', namely `5.5' In the second argument of `($)', namely `mkState 5.5' In the expression: doStuff2 $ mkState 5.5
I would like to be able to understand why the type synonym introduced causes this error and how to decrypt the error message.
source share