Typeclass Constraint Causing Typechecker to Fail

Below I have a contrived example. Please do not take this to be real world code. f :: (Show a) => Int -> (Int -> a) -> Int -> IO a f i g x = do print i return $ g (x + i) foo :: Bool -> IO (Either [Int] [String]) foo b = do let helper = f 2 if b then Left <$> sequence (fmap (helper negate) [0,1]) else Right <$> sequence (fmap (helper show) [0,1]) The above will fail stating Example.hs:14:35: Couldn't match type ‘Int’ with ‘[Char]’ Expected type: Int -> IO String Actual type: Int -> IO Int In the first argument of ‘fmap’, namely ‘(helper show)’ In the first argument of ‘sequence’, namely ‘(fmap (helper show) [0, 1])’ Example.hs:14:42: Couldn't match type ‘[Char]’ with ‘Int’ Expected type: Int -> Int Actual type: Int -> String In the first argument of ‘helper’, namely ‘show’ In the first argument of ‘fmap’, namely ‘(helper show)’ However, if I simply change f's type signature to not have the typeclass constraint, the type checker is happy: f :: Int -> (Int -> a) -> Int -> IO a Another possibility to remove the problem is to remove the let statement and instead put the entire expression in. foo :: Bool -> IO (Either [Int] [String]) foo b = do if b then Left <$> sequence (fmap (f 2 negate) [0,1]) else Right <$> sequence (fmap (f 2 show) [0,1]) This seems to be a bug in the typechecker, and maybe it is a well known issue. Can someone please confirm that this is a bug and whether or not it is known? James

The dreaded monomorphism restriction strikes again, namely during the binding of let helper = f 2. Adding an explicit type signature let helper :: Show a => (Int -> a) -> Int -> IO a helper = f 2 or -XNoMonomorphismRestriction does the trick. On 4/20/2016 1:24 AM, James M wrote:
Below I have a contrived example. Please do not take this to be real world code.
f :: (Show a) => Int -> (Int -> a) -> Int -> IO a f i g x = do print i return $ g (x + i)
foo :: Bool -> IO (Either [Int] [String]) foo b = do let helper = f 2 if b then Left <$> sequence (fmap (helper negate) [0,1]) else Right <$> sequence (fmap (helper show) [0,1])
The above will fail stating
Example.hs:14:35:
Couldn't match type ‘Int’ with ‘[Char]’
Expected type: Int -> IO String
Actual type: Int -> IO Int
In the first argument of ‘fmap’, namely ‘(helper show)’
In the first argument of ‘sequence’, namely
‘(fmap (helper show) [0, 1])’
Example.hs:14:42:
Couldn't match type ‘[Char]’ with ‘Int’
Expected type: Int -> Int
Actual type: Int -> String
In the first argument of ‘helper’, namely ‘show’
In the first argument of ‘fmap’, namely ‘(helper show)’
However, if I simply change f's type signature to not have the typeclass constraint, the type checker is happy: f :: Int -> (Int -> a) -> Int -> IO a
Another possibility to remove the problem is to remove the let statement and instead put the entire expression in.
foo :: Bool -> IO (Either [Int] [String]) foo b = do if b then Left <$> sequence (fmap (f 2 negate) [0,1]) else Right <$> sequence (fmap (f 2 show) [0,1])
This seems to be a bug in the typechecker, and maybe it is a well known issue.
Can someone please confirm that this is a bug and whether or not it is known?
James
_______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe

On Tue, Apr 19, 2016 at 04:24:26PM -0700, James M wrote:
Below I have a contrived example. Please do not take this to be real world code.
f :: (Show a) => Int -> (Int -> a) -> Int -> IO a f i g x = do print i return $ g (x + i)
foo :: Bool -> IO (Either [Int] [String]) foo b = do let helper = f 2 if b then Left <$> sequence (fmap (helper negate) [0,1]) else Right <$> sequence (fmap (helper show) [0,1])
The above will fail stating...
<snip>
This seems to be a bug in the typechecker, and maybe it is a well known issue.
Can someone please confirm that this is a bug and whether or not it is known?
I believe you have discovered everyone's favorite Haskell feature: https://wiki.haskell.org/Monomorphism_restriction
participants (3)
-
Bryan Richter
-
David Kraeutmann
-
James M