Quantcast
Channel: How does GADTs affect type inference in this case? - Stack Overflow
Viewing all articles
Browse latest Browse all 2

How does GADTs affect type inference in this case?

$
0
0

Say I have a monad that emits soft failure through Writer. A simplified version goes like this (for the record, I'm using GHC 9.0.2):

{-# LANGUAGE BlockArguments #-}{-# LANGUAGE FlexibleContexts #-}-- {-# LANGUAGE GADTs #-}{-# LANGUAGE ScopedTypeVariables #-}module Lib whereimport Control.Monad.Writer.CPSimport Data.Maybeverify :: MonadWriter [String] m => some -> args -> m ()verify _ _ = fix \(_ :: m ()) ->  do    let warn = tell . (: [])        a = Just 1 :: Maybe Int        b = Just [1, 23] :: Maybe [Int]        c = Just (id :: forall a. a -> a)        -- isJust' :: String -> Maybe a -> m ()        isJust' tag v = unless (isJust v) do          warn $ tag <> " is Nothing"    isJust'"a" a    isJust'"b" b    isJust'"c" c

All goes fine until I add GADTs extension, then GHC fails to find the most general type for isJust':

• Couldn't match type ‘[Int]’ with ‘Int’      Expected: Maybe Int        Actual: Maybe [Int]• In the second argument of ‘isJust'’, namely ‘b’      In a stmt of a 'do' block: isJust'"b" b      In the expression:        do let warn = tell . (: [])               a = ...               ....           isJust'"a" a           isJust'"b" b           isJust'"c" c   |22 |     isJust'"b" b   |                 ^/var/tmp/demo/src/Lib.hs:23:17: error:• Couldn't match type ‘a0 -> a0’ with ‘Int’      Expected: Maybe Int        Actual: Maybe (a0 -> a0)• In the second argument of ‘isJust'’, namely ‘c’      In a stmt of a 'do' block: isJust'"c" c      In the expression:        do let warn = tell . (: [])               a = ...               ....           isJust'"a" a           isJust'"b" b           isJust'"c" c   |23 |     isJust'"c" c   |                 ^

At which point I have to uncomment type annotation for isJust' to get this to type check - I'm wondering what is at play here, I don't think I'm using any GADTs features?

Side note 1: I usually just slam a NoMonomorphismRestriction to see if it helps, it didn't.

Side note 2: That use of fix is just for getting a hold on that m in the presence of ScopedTypeVariables - a side question is whether there are better ways to do this without relying on verify having an explicit type signature (say this function is defined inside an instance).


Viewing all articles
Browse latest Browse all 2

Latest Images

Trending Articles



Latest Images

<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>
<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596344.js" async> </script>