diff --git a/src/Named.hs b/src/Named.hs index 91e5285..00a1c57 100644 --- a/src/Named.hs +++ b/src/Named.hs @@ -153,6 +153,35 @@ operator: '!' #handle logfile @ += An issue with with polymorphic return types + +A limitation of 'defaults' is that it is not possible to pass it to a function with a polymorphic return type. In particular: to mtl-style functions. The following code produces a compilation error: + +@ +foo :: "x" ':?' Int -> m Int + +bar :: m Int +bar = foo '!' 'defaults' +@ + +A workaround is to return a newtype wrapper around @m@: + +@ +newtype M m a = M { runM :: m a } + deriving (Functor, Applicative, Monad) + +foo :: "x" ':?' Int -> M m Int + +bar :: M m Int +bar = foo '!' 'defaults' + +bar' :: m Int +bar' = runM (foo '!' 'defaults') +@ + +Note: the type signature of 'bar' is required. + +See [issue #15](https://github.com/monadfix/named/issues/15) "Problem with type inference caused by @! defaults@" for details. -} module Named ( diff --git a/test/Test.hs b/test/Test.hs index c965881..6c2b89d 100644 --- a/test/Test.hs +++ b/test/Test.hs @@ -127,6 +127,28 @@ test6_raw (Just f) = f 42 inspect $ 'test6 ==- 'test6_raw +newtype M m a = M { runM :: m a } + deriving (Functor, Applicative, Monad) + +-- must typecheck: + +test7_1 :: "x" :? Int -> M m Int +test7_1 = undefined + +test7_2 :: M m Int +test7_2 = test7_1 ! defaults + +test7_3 :: m Int +test7_3 = runM (test7_1 ! defaults) + +-- doesn't typecheck (yet): +-- +-- test7_4 :: "x" :? Int -> m Int +-- test7_4 = undefined + +-- test7_5 :: m Int +-- test7_5 = test7_1 ! defaults + main :: IO () main = do void test1_1