Last active
December 26, 2015 16:39
-
-
Save YoEight/7181580 to your computer and use it in GitHub Desktop.
GHC (7.6.3) GADTs bug ? Output is GHC output when GADTs is enabled
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
ghc -Wall -ferror-spans -fforce-recomp -c /home/yorick/Desktop/process.hs | |
/home/yorick/Desktop/process.hs:34:9-34: | |
Couldn't match type `a1' with `a2' | |
because type variable `a2' would escape its scope | |
This (rigid, skolem) type variable is bound by | |
a type expected by the context: | |
m a2 -> (a2 -> Process m a) -> Process m a -> r | |
The following variables have types that mention a1 | |
awaiting :: m a1 -> (a1 -> Process m a) -> Process m a -> r | |
(bound at /home/yorick/Desktop/process.hs:30:13) | |
Expected type: m a2 -> (a2 -> Process m a) -> Process m a -> r | |
Actual type: m a1 -> (a1 -> Process m a) -> Process m a -> r | |
In the second argument of `k', namely `awaiting' | |
In the expression: k yielding awaiting onHalt | |
In the expression: | |
let | |
yielding [] next = let ... in action onYield onAwait onHalt | |
yielding (x : xs) next = let ... in action onYield onAwait onHalt | |
awaiting req recv fb = let ... in action onYield onAwait onHalt | |
in k yielding awaiting onHalt | |
/home/yorick/Desktop/process.hs:41:5-28: | |
Couldn't match type `a0' with `a' | |
because type variable `a' would escape its scope | |
This (rigid, skolem) type variable is bound by | |
a type expected by the context: | |
m a -> (a -> Process m o) -> Process m o -> m [o] | |
The following variables have types that mention a0 | |
onAwait :: m a0 -> (a0 -> Process m o) -> Process m o -> m [o] | |
(bound at /home/yorick/Desktop/process.hs:39:9) | |
Expected type: m a -> (a -> Process m o) -> Process m o -> m [o] | |
Actual type: m a0 -> (a0 -> Process m o) -> Process m o -> m [o] | |
In the second argument of `k', namely `onAwait' | |
In the expression: k onYield onAwait onHalt | |
In the expression: | |
let | |
onYield xs next = liftM (xs ++) (collectProcess next) | |
onAwait req recv _ = collectProcess . recv =<< req | |
onHalt = return [] | |
in k onYield onAwait onHalt |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{-# LANGUAGE ExistentialQuantification #-} | |
{-# LANGUAGE RankNTypes #-} | |
-- {-# LANGUAGE GADTs #-} when enabled, the code doesn't compile | |
module Data.Process where | |
import Control.Monad (liftM) | |
newtype Process m o = Process | |
{ unProcess :: | |
forall r. | |
([o] -> Process m o -> r) -> | |
(forall a. m a -> (a -> Process m o) -> Process m o -> r) -> | |
r -> | |
r } | |
instance Monad (Process m) where | |
return a = Process $ \onYield _ _ -> onYield [a] halt | |
Process k >>= f = Process $ \onYield onAwait onHalt -> | |
let yielding [] next = | |
let (Process action) = next >>= f in | |
action onYield onAwait onHalt | |
yielding (x:xs) next = | |
let (Process action) = append (f x) (rest >>= f) | |
rest = | |
if null xs | |
then next | |
else yieldAllWith xs next in | |
action onYield onAwait onHalt | |
awaiting req recv fb = | |
let (Process action) = | |
awaitWith req ((f =<<) . recv) (fb >>= f) in | |
action onYield onAwait onHalt in | |
k yielding awaiting onHalt | |
collectProcess :: Monad m => Process m o -> m [o] | |
collectProcess (Process k) = | |
let onYield xs next = liftM (xs ++) (collectProcess next) | |
onAwait req recv _ = collectProcess . recv =<< req | |
onHalt = return [] in | |
k onYield onAwait onHalt | |
halt :: Process m o | |
halt = Process $ \_ _ h -> h | |
awaitWith :: m a -> (a -> Process m o) -> Process m o -> Process m o | |
awaitWith req k fb = Process $ \_ onAwait _ -> onAwait req k fb | |
yieldAllWith :: [o] -> Process m o -> Process m o | |
yieldAllWith xs next = Process $ \onYield _ _ -> onYield xs next | |
append :: Process m o -> Process m o -> Process m o | |
append (Process kl) p2@(Process kr) = Process $ \onYield onAwait onHalt -> | |
kl (\xs next -> onYield xs (append next p2)) | |
(\r k fb -> onAwait r (\a -> append (k a) p2) (append fb p2)) | |
(kr onYield onAwait onHalt) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
[14/02/22-20:11:28] if you add a {-# LANGUAGE NoMonoLocalBinds #-} then it works even with GADTs
on #ghc on freenode