Skip to content

Instantly share code, notes, and snippets.

@YoEight
Last active December 26, 2015 16:39
Show Gist options
  • Save YoEight/7181580 to your computer and use it in GitHub Desktop.
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
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
{-# 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)
@cartazio
Copy link

[14/02/22-20:11:28] if you add a {-# LANGUAGE NoMonoLocalBinds #-} then it works even with GADTs

on #ghc on freenode

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment