Skip to content

Instantly share code, notes, and snippets.

@cjay
Created May 7, 2022 23:37
Show Gist options
  • Save cjay/b058a0a4e2071a4969c81a6ae2df4045 to your computer and use it in GitHub Desktop.
Save cjay/b058a0a4e2071a4969c81a6ae2df4045 to your computer and use it in GitHub Desktop.
Comparison: How simplified subsumption interacts with newtype and with type aliases
{-# LANGUAGE RankNTypes #-}
import Control.Monad.Cont (MonadIO)
-- Comparison: How simplified subsumption interacts with newtype and with type aliases
-- example with type alias:
type Foo a = forall m. MonadIO m => m a
foo :: forall m a. MonadIO m => Int -> m a
foo = foo
bar :: MonadIO m => (Int -> Foo ()) -> m ()
-- doesn't work with 9.2.2
-- bar = ($ 1)
bar x = x 1
baz :: MonadIO m => m ()
-- doesn't work with 9.2.2, works with 8.10.7
-- baz = bar foo
-- works with ghc 8.10.7 and 9.2.2
baz = bar (\x -> foo x)
-- equivalent example with newtype:
newtype FooN a = FooN { unFooN :: forall m. MonadIO m => m a}
unFooN2 :: MonadIO m => FooN a -> m a
unFooN2 (FooN m) = m
barN :: MonadIO m => (Int -> FooN ()) -> m ()
-- the generated field selector unFooN only works with 8.10.7
barN = unFooN2 . ($ 1)
bazN :: MonadIO m => m ()
-- !!! doesn't even work with ghc 8.10.7 !!!
-- bazN = barN (FooN . foo)
-- works with ghc 8.10.7 and 9.2.2
bazN = barN (\x -> FooN (foo x))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment