[GHC] #9633: PolyKinds in 7.8.2 vs 7.8.3

#9633: PolyKinds in 7.8.2 vs 7.8.3 -------------------------------------+------------------------------------- Reporter: crockeea | Owner: Type: bug | Status: new Priority: normal | Milestone: Component: Compiler | Version: 7.8.3 Keywords: PolyKinds | Operating System: Architecture: Unknown/Multiple | Unknown/Multiple Difficulty: Unknown | Type of failure: GHC Blocked By: | rejects valid program Related Tickets: | Test Case: | Blocking: | Differential Revisions: -------------------------------------+------------------------------------- The following code '''compiles''' with GHC 7.8.2. This code has been distilled down from a larger example where I needed `-XPolyKinds` in Bar.hs but not in Foo.hs. In addition, the `modify` function is supposed to modify a mutable `Data.Vector`, hence the inner `go` function has the intended type of `Int -> m ()`, though strictly speaking it could return any value since everything is discarded by the `forM_`. {{{ -- {-# LANGUAGE PolyKinds #-} module Foo where import Control.Monad (forM_) import Control.Monad.Primitive import Bar -- Vector signatures unsafeRead :: (PrimMonad m) => v (PrimState m) a -> Int -> m a unsafeRead = error "type only" unsafeWrite :: (PrimMonad m) => v (PrimState m) a -> Int -> a -> m () unsafeWrite = error "type only" modify :: Int -> Bar v r modify p = Bar (p-1) $ \y -> do let go i = do a <- unsafeRead y i unsafeWrite y i a --return a forM_ [0..(p-1)] go }}} {{{ {-# LANGUAGE RankNTypes, PolyKinds #-} module Bar where import Control.Monad.Primitive data Bar v r = Bar Int (forall s . (PrimMonad s) => v (PrimState s) r -> s ()) }}} In 7.8.3, this above code results in the error (with `-fprint-explicit- kinds`) {{{ Foo.hs:19:23: Couldn't match type ‘a0’ with ‘r’ ‘a0’ is untouchable inside the constraints (PrimMonad m, (~) * (PrimState m) (PrimState s)) bound by the inferred type of go :: (PrimMonad m, (~) * (PrimState m) (PrimState s)) => Int -> m () at Foo.hs:(18,7)-(20,23) ‘r’ is a rigid type variable bound by the type signature for modify :: Int -> Bar * v r at Foo.hs:16:11 Expected type: v0 (PrimState m) a0 Actual type: v (PrimState s) r ... In the first argument of ‘unsafeRead’, namely ‘y’ In a stmt of a 'do' block: a <- unsafeRead y i Foo.hs:20:19: Couldn't match type ‘v1’ with ‘v’ ‘v1’ is untouchable inside the constraints (PrimMonad m, (~) * (PrimState m) (PrimState s)) bound by the inferred type of go :: (PrimMonad m, (~) * (PrimState m) (PrimState s)) => Int -> m () at Foo.hs:(18,7)-(20,23) ‘v’ is a rigid type variable bound by the type signature for modify :: Int -> Bar * v r at Foo.hs:16:11 Expected type: v1 (PrimState m) a0 Actual type: v (PrimState s) r ... In the first argument of ‘unsafeWrite’, namely ‘y’ ... Failed, modules loaded: Bar. }}} After much digging, I found that enabling `-XPolyKinds` in Foo.hs gives a more meaningful error: {{{ Foo.hs:19:23: Could not deduce ((~) (* -> k -> *) v v0) ... Expected type: v0 (PrimState m) a0 Actual type: v (PrimState s) r ... In the first argument of ‘unsafeRead’, namely ‘y’ In a stmt of a 'do' block: a <- unsafeRead y i Foo.hs:20:19: Could not deduce ((~) (* -> k -> *) v v1) ... Expected type: v1 (PrimState m) a0 Actual type: v (PrimState s) r ... In the first argument of ‘unsafeWrite’, namely ‘y’ In a stmt of a 'do' block: unsafeWrite y i a Failed, modules loaded: Bar. }}} Adding `PolyKinds` to Foo.hs ''and'' uncommenting `return a` results in the error: {{{ Foo.hs:17:12: Couldn't match kind ‘k’ with ‘k1’ because type variable ‘k1’ would escape its scope This (rigid, skolem) type variable is bound by the type signature for modify :: Int -> Bar k1 v r at Foo.hs:16:11-24 Expected type: Bar k1 v r Actual type: Bar k v0 r0 ... In the expression: Bar (p - 1) $ \ y -> do { let ...; forM_ [0 .. (p - 1)] go } ... Foo.hs:18:7: Kind incompatibility when matching types: v0 :: * -> k -> * v1 :: * -> * -> * ... When checking that ‘go’ has the inferred type ‘forall (k :: BOX) (m :: * -> *) b (v :: * -> * -> *) (v1 :: * -> * -> *). ((~) (* -> k -> *) v0 v, (~) k r0 b, (~) (* -> k -> *) v0 v1, PrimMonad m, (~) * (PrimState m) (PrimState s)) => Int -> m b’ Probable cause: the inferred type is ambiguous In the expression: do { let go i = ...; forM_ [0 .. (p - 1)] go } ... Failed, modules loaded: Bar. }}} These errors can be resolved by modifying the original code above in any of the following ways: 1. Remove `-XPolyKinds` from Bar.hs 2. Add an explicit kind signature to the `v :: * -> * -> *` parameter of type `Bar` 3. With `PolyKinds` in Bar but *not* Foo, uncommenting `return a` make GHC 7.8.3. compile What I'm trying to understand is 1. Why there is different behavior from 7.8.2 to 7.8.3. There doesn't seem to be anything addressing `PolyKinds` in the [http://www.haskell.org/ghc/docs/7.8.3/html/users_guide/release-7-8-3.html release notes vs 7.8.2] . 2. In the event the above code should not compile with 7.8.3, there error message could be much clearer. The first error message above didn't help me understand that `PolyKinds` was to blame, while the second error did a better job, and the third was very clearly a `PolyKinds` issue (i.e. `kind mismatch`) 3. For the third resolution option above, I can't see any reason that adding `return a` to the inner `go` function should make the code compile while leaving it out makes the code somehow ambiguous. This, if nothing else, seems like a bug. -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/9633 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#9633: PolyKinds in 7.8.2 vs 7.8.3 -------------------------------------+------------------------------------- Reporter: crockeea | Owner: Type: bug | Status: new Priority: normal | Milestone: Component: Compiler | Version: 7.8.3 Resolution: | Keywords: PolyKinds Operating System: | Architecture: Unknown/Multiple Unknown/Multiple | Difficulty: Unknown Type of failure: GHC | Blocked By: rejects valid program | Related Tickets: Test Case: | Blocking: | Differential Revisions: | -------------------------------------+------------------------------------- Comment (by simonpj): Where does `Control.Monad.Primitive` come from? -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/9633#comment:1 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#9633: PolyKinds in 7.8.2 vs 7.8.3 -------------------------------------+------------------------------------- Reporter: crockeea | Owner: Type: bug | Status: new Priority: normal | Milestone: Component: Compiler | Version: 7.8.3 Resolution: | Keywords: PolyKinds Operating System: | Architecture: Unknown/Multiple Unknown/Multiple | Difficulty: Unknown Type of failure: GHC | Blocked By: rejects valid program | Related Tickets: Test Case: | Blocking: | Differential Revisions: | -------------------------------------+------------------------------------- Comment (by refold): Replying to [comment:1 simonpj]:
Where does `Control.Monad.Primitive` come from?
From [http://hackage.haskell.org/package/primitive-0.5.3.0/docs/Control- Monad-Primitive.html this package]. -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/9633#comment:2 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#9633: PolyKinds in 7.8.2 vs 7.8.3 -------------------------------------+------------------------------------- Reporter: crockeea | Owner: Type: bug | Status: new Priority: normal | Milestone: Component: Compiler | Version: 7.8.3 Resolution: | Keywords: PolyKinds Operating System: | Architecture: Unknown/Multiple Unknown/Multiple | Difficulty: Unknown Type of failure: GHC | Blocked By: rejects valid program | Related Tickets: Test Case: | Blocking: | Differential Revisions: | -------------------------------------+------------------------------------- Comment (by goldfire): I looked a little at this, and `Control.Monad.Primitive` isn't integral to the problem. Just replace `PrimMonad` with `Monad` and use a fresh type family for `PrimState`. Didn't figure out much beyond that, but I only tried for 5 minutes. -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/9633#comment:3 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#9633: PolyKinds in 7.8.2 vs 7.8.3 -------------------------------------+------------------------------------- Reporter: crockeea | Owner: Type: bug | Status: new Priority: normal | Milestone: Component: Compiler | Version: 7.8.3 Resolution: | Keywords: PolyKinds Operating System: | Architecture: Unknown/Multiple Unknown/Multiple | Difficulty: Unknown Type of failure: GHC | Blocked By: rejects valid program | Related Tickets: Test Case: | Blocking: | Differential Revisions: | -------------------------------------+------------------------------------- Description changed by crockeea: Old description:
The following code '''compiles''' with GHC 7.8.2.
This code has been distilled down from a larger example where I needed `-XPolyKinds` in Bar.hs but not in Foo.hs. In addition, the `modify` function is supposed to modify a mutable `Data.Vector`, hence the inner `go` function has the intended type of `Int -> m ()`, though strictly speaking it could return any value since everything is discarded by the `forM_`.
{{{ -- {-# LANGUAGE PolyKinds #-}
module Foo where
import Control.Monad (forM_) import Control.Monad.Primitive
import Bar
-- Vector signatures unsafeRead :: (PrimMonad m) => v (PrimState m) a -> Int -> m a unsafeRead = error "type only" unsafeWrite :: (PrimMonad m) => v (PrimState m) a -> Int -> a -> m () unsafeWrite = error "type only"
modify :: Int -> Bar v r modify p = Bar (p-1) $ \y -> do let go i = do a <- unsafeRead y i unsafeWrite y i a --return a forM_ [0..(p-1)] go }}}
{{{ {-# LANGUAGE RankNTypes, PolyKinds #-} module Bar where
import Control.Monad.Primitive
data Bar v r = Bar Int (forall s . (PrimMonad s) => v (PrimState s) r -> s ()) }}}
In 7.8.3, this above code results in the error (with `-fprint-explicit- kinds`)
{{{ Foo.hs:19:23: Couldn't match type ‘a0’ with ‘r’ ‘a0’ is untouchable inside the constraints (PrimMonad m, (~) * (PrimState m) (PrimState s)) bound by the inferred type of go :: (PrimMonad m, (~) * (PrimState m) (PrimState s)) => Int -> m () at Foo.hs:(18,7)-(20,23) ‘r’ is a rigid type variable bound by the type signature for modify :: Int -> Bar * v r at Foo.hs:16:11 Expected type: v0 (PrimState m) a0 Actual type: v (PrimState s) r ... In the first argument of ‘unsafeRead’, namely ‘y’ In a stmt of a 'do' block: a <- unsafeRead y i
Foo.hs:20:19: Couldn't match type ‘v1’ with ‘v’ ‘v1’ is untouchable inside the constraints (PrimMonad m, (~) * (PrimState m) (PrimState s)) bound by the inferred type of go :: (PrimMonad m, (~) * (PrimState m) (PrimState s)) => Int -> m () at Foo.hs:(18,7)-(20,23) ‘v’ is a rigid type variable bound by the type signature for modify :: Int -> Bar * v r at Foo.hs:16:11 Expected type: v1 (PrimState m) a0 Actual type: v (PrimState s) r ... In the first argument of ‘unsafeWrite’, namely ‘y’ ... Failed, modules loaded: Bar. }}}
After much digging, I found that enabling `-XPolyKinds` in Foo.hs gives a more meaningful error:
{{{ Foo.hs:19:23: Could not deduce ((~) (* -> k -> *) v v0) ... Expected type: v0 (PrimState m) a0 Actual type: v (PrimState s) r ... In the first argument of ‘unsafeRead’, namely ‘y’ In a stmt of a 'do' block: a <- unsafeRead y i
Foo.hs:20:19: Could not deduce ((~) (* -> k -> *) v v1) ... Expected type: v1 (PrimState m) a0 Actual type: v (PrimState s) r ... In the first argument of ‘unsafeWrite’, namely ‘y’ In a stmt of a 'do' block: unsafeWrite y i a Failed, modules loaded: Bar. }}}
Adding `PolyKinds` to Foo.hs ''and'' uncommenting `return a` results in the error:
{{{ Foo.hs:17:12: Couldn't match kind ‘k’ with ‘k1’ because type variable ‘k1’ would escape its scope This (rigid, skolem) type variable is bound by the type signature for modify :: Int -> Bar k1 v r at Foo.hs:16:11-24 Expected type: Bar k1 v r Actual type: Bar k v0 r0 ... In the expression: Bar (p - 1) $ \ y -> do { let ...; forM_ [0 .. (p - 1)] go } ...
Foo.hs:18:7: Kind incompatibility when matching types: v0 :: * -> k -> * v1 :: * -> * -> * ... When checking that ‘go’ has the inferred type ‘forall (k :: BOX) (m :: * -> *) b (v :: * -> * -> *) (v1 :: * -> * -> *). ((~) (* -> k -> *) v0 v, (~) k r0 b, (~) (* -> k -> *) v0 v1, PrimMonad m, (~) * (PrimState m) (PrimState s)) => Int -> m b’ Probable cause: the inferred type is ambiguous In the expression: do { let go i = ...; forM_ [0 .. (p - 1)] go } ... Failed, modules loaded: Bar.
}}}
These errors can be resolved by modifying the original code above in any of the following ways:
1. Remove `-XPolyKinds` from Bar.hs 2. Add an explicit kind signature to the `v :: * -> * -> *` parameter of type `Bar` 3. With `PolyKinds` in Bar but *not* Foo, uncommenting `return a` make GHC 7.8.3. compile
What I'm trying to understand is 1. Why there is different behavior from 7.8.2 to 7.8.3. There doesn't seem to be anything addressing `PolyKinds` in the [http://www.haskell.org/ghc/docs/7.8.3/html/users_guide/release-7-8-3.html release notes vs 7.8.2] . 2. In the event the above code should not compile with 7.8.3, there error message could be much clearer. The first error message above didn't help me understand that `PolyKinds` was to blame, while the second error did a better job, and the third was very clearly a `PolyKinds` issue (i.e. `kind mismatch`) 3. For the third resolution option above, I can't see any reason that adding `return a` to the inner `go` function should make the code compile while leaving it out makes the code somehow ambiguous. This, if nothing else, seems like a bug.
New description: The following code '''compiles''' with GHC 7.8.2. This code has been distilled down from a larger example where I needed `-XPolyKinds` in Bar.hs but not in Foo.hs. In addition, the `modify` function is supposed to modify a mutable `Data.Vector`, hence the inner `go` function has the intended type of `Int -> m ()`, though strictly speaking it could return any value since everything is discarded by the `forM_`. {{{ -- {-# LANGUAGE PolyKinds #-} module Foo where import Control.Monad (forM_) import Bar -- Vector signatures unsafeRead :: (PrimMonad m) => v (PrimState m) a -> Int -> m a unsafeRead = error "type only" unsafeWrite :: (PrimMonad m) => v (PrimState m) a -> Int -> a -> m () unsafeWrite = error "type only" modify :: Int -> Bar v r modify p = Bar (p-1) $ \y -> do let go i = do a <- unsafeRead y i unsafeWrite y i a --return a forM_ [0..(p-1)] go }}} {{{ {-# LANGUAGE RankNTypes, KindSignatures, TypeFamilies, PolyKinds #-} module Bar where class Monad m => PrimMonad (m :: * -> *) where type family PrimState (m :: * -> *) :: * data Bar v r = Bar Int (forall s . (PrimMonad s) => v (PrimState s) r -> s ()) }}} In 7.8.3, this above code results in the error (with `-fprint-explicit- kinds`) {{{ Foo.hs:19:23: Couldn't match type ‘a0’ with ‘r’ ‘a0’ is untouchable inside the constraints (PrimMonad m, (~) * (PrimState m) (PrimState s)) bound by the inferred type of go :: (PrimMonad m, (~) * (PrimState m) (PrimState s)) => Int -> m () at Foo.hs:(18,7)-(20,23) ‘r’ is a rigid type variable bound by the type signature for modify :: Int -> Bar * v r at Foo.hs:16:11 Expected type: v0 (PrimState m) a0 Actual type: v (PrimState s) r ... In the first argument of ‘unsafeRead’, namely ‘y’ In a stmt of a 'do' block: a <- unsafeRead y i Foo.hs:20:19: Couldn't match type ‘v1’ with ‘v’ ‘v1’ is untouchable inside the constraints (PrimMonad m, (~) * (PrimState m) (PrimState s)) bound by the inferred type of go :: (PrimMonad m, (~) * (PrimState m) (PrimState s)) => Int -> m () at Foo.hs:(18,7)-(20,23) ‘v’ is a rigid type variable bound by the type signature for modify :: Int -> Bar * v r at Foo.hs:16:11 Expected type: v1 (PrimState m) a0 Actual type: v (PrimState s) r ... In the first argument of ‘unsafeWrite’, namely ‘y’ ... Failed, modules loaded: Bar. }}} After much digging, I found that enabling `-XPolyKinds` in Foo.hs gives a more meaningful error: {{{ Foo.hs:19:23: Could not deduce ((~) (* -> k -> *) v v0) ... Expected type: v0 (PrimState m) a0 Actual type: v (PrimState s) r ... In the first argument of ‘unsafeRead’, namely ‘y’ In a stmt of a 'do' block: a <- unsafeRead y i Foo.hs:20:19: Could not deduce ((~) (* -> k -> *) v v1) ... Expected type: v1 (PrimState m) a0 Actual type: v (PrimState s) r ... In the first argument of ‘unsafeWrite’, namely ‘y’ In a stmt of a 'do' block: unsafeWrite y i a Failed, modules loaded: Bar. }}} Adding `PolyKinds` to Foo.hs ''and'' uncommenting `return a` results in the error: {{{ Foo.hs:17:12: Couldn't match kind ‘k’ with ‘k1’ because type variable ‘k1’ would escape its scope This (rigid, skolem) type variable is bound by the type signature for modify :: Int -> Bar k1 v r at Foo.hs:16:11-24 Expected type: Bar k1 v r Actual type: Bar k v0 r0 ... In the expression: Bar (p - 1) $ \ y -> do { let ...; forM_ [0 .. (p - 1)] go } ... Foo.hs:18:7: Kind incompatibility when matching types: v0 :: * -> k -> * v1 :: * -> * -> * ... When checking that ‘go’ has the inferred type ‘forall (k :: BOX) (m :: * -> *) b (v :: * -> * -> *) (v1 :: * -> * -> *). ((~) (* -> k -> *) v0 v, (~) k r0 b, (~) (* -> k -> *) v0 v1, PrimMonad m, (~) * (PrimState m) (PrimState s)) => Int -> m b’ Probable cause: the inferred type is ambiguous In the expression: do { let go i = ...; forM_ [0 .. (p - 1)] go } ... Failed, modules loaded: Bar. }}} These errors can be resolved by modifying the original code above in any of the following ways: 1. Remove `-XPolyKinds` from Bar.hs 2. Add an explicit kind signature to the `v :: * -> * -> *` parameter of type `Bar` 3. With `PolyKinds` in Bar but *not* Foo, uncommenting `return a` make GHC 7.8.3. compile What I'm trying to understand is 1. Why there is different behavior from 7.8.2 to 7.8.3. There doesn't seem to be anything addressing `PolyKinds` in the [http://www.haskell.org/ghc/docs/7.8.3/html/users_guide/release-7-8-3.html release notes vs 7.8.2] . 2. In the event the above code should not compile with 7.8.3, there error message could be much clearer. The first error message above didn't help me understand that `PolyKinds` was to blame, while the second error did a better job, and the third was very clearly a `PolyKinds` issue (i.e. `kind mismatch`) 3. For the third resolution option above, I can't see any reason that adding `return a` to the inner `go` function should make the code compile while leaving it out makes the code somehow ambiguous. This, if nothing else, seems like a bug. -- -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/9633#comment:4 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#9633: PolyKinds in 7.8.2 vs 7.8.3 -------------------------------------+------------------------------------- Reporter: crockeea | Owner: Type: bug | Status: new Priority: normal | Milestone: Component: Compiler | Version: 7.8.3 Resolution: | Keywords: PolyKinds Operating System: | Architecture: Unknown/Multiple Unknown/Multiple | Difficulty: Unknown Type of failure: GHC | Blocked By: rejects valid program | Related Tickets: Test Case: | Blocking: | Differential Revisions: | -------------------------------------+------------------------------------- Description changed by crockeea: Old description:
The following code '''compiles''' with GHC 7.8.2.
This code has been distilled down from a larger example where I needed `-XPolyKinds` in Bar.hs but not in Foo.hs. In addition, the `modify` function is supposed to modify a mutable `Data.Vector`, hence the inner `go` function has the intended type of `Int -> m ()`, though strictly speaking it could return any value since everything is discarded by the `forM_`.
{{{ -- {-# LANGUAGE PolyKinds #-}
module Foo where
import Control.Monad (forM_) import Bar
-- Vector signatures unsafeRead :: (PrimMonad m) => v (PrimState m) a -> Int -> m a unsafeRead = error "type only" unsafeWrite :: (PrimMonad m) => v (PrimState m) a -> Int -> a -> m () unsafeWrite = error "type only"
modify :: Int -> Bar v r modify p = Bar (p-1) $ \y -> do let go i = do a <- unsafeRead y i unsafeWrite y i a --return a forM_ [0..(p-1)] go }}}
{{{ {-# LANGUAGE RankNTypes, KindSignatures, TypeFamilies, PolyKinds #-} module Bar where
class Monad m => PrimMonad (m :: * -> *) where type family PrimState (m :: * -> *) :: *
data Bar v r = Bar Int (forall s . (PrimMonad s) => v (PrimState s) r -> s ()) }}}
In 7.8.3, this above code results in the error (with `-fprint-explicit- kinds`)
{{{ Foo.hs:19:23: Couldn't match type ‘a0’ with ‘r’ ‘a0’ is untouchable inside the constraints (PrimMonad m, (~) * (PrimState m) (PrimState s)) bound by the inferred type of go :: (PrimMonad m, (~) * (PrimState m) (PrimState s)) => Int -> m () at Foo.hs:(18,7)-(20,23) ‘r’ is a rigid type variable bound by the type signature for modify :: Int -> Bar * v r at Foo.hs:16:11 Expected type: v0 (PrimState m) a0 Actual type: v (PrimState s) r ... In the first argument of ‘unsafeRead’, namely ‘y’ In a stmt of a 'do' block: a <- unsafeRead y i
Foo.hs:20:19: Couldn't match type ‘v1’ with ‘v’ ‘v1’ is untouchable inside the constraints (PrimMonad m, (~) * (PrimState m) (PrimState s)) bound by the inferred type of go :: (PrimMonad m, (~) * (PrimState m) (PrimState s)) => Int -> m () at Foo.hs:(18,7)-(20,23) ‘v’ is a rigid type variable bound by the type signature for modify :: Int -> Bar * v r at Foo.hs:16:11 Expected type: v1 (PrimState m) a0 Actual type: v (PrimState s) r ... In the first argument of ‘unsafeWrite’, namely ‘y’ ... Failed, modules loaded: Bar. }}}
After much digging, I found that enabling `-XPolyKinds` in Foo.hs gives a more meaningful error:
{{{ Foo.hs:19:23: Could not deduce ((~) (* -> k -> *) v v0) ... Expected type: v0 (PrimState m) a0 Actual type: v (PrimState s) r ... In the first argument of ‘unsafeRead’, namely ‘y’ In a stmt of a 'do' block: a <- unsafeRead y i
Foo.hs:20:19: Could not deduce ((~) (* -> k -> *) v v1) ... Expected type: v1 (PrimState m) a0 Actual type: v (PrimState s) r ... In the first argument of ‘unsafeWrite’, namely ‘y’ In a stmt of a 'do' block: unsafeWrite y i a Failed, modules loaded: Bar. }}}
Adding `PolyKinds` to Foo.hs ''and'' uncommenting `return a` results in the error:
{{{ Foo.hs:17:12: Couldn't match kind ‘k’ with ‘k1’ because type variable ‘k1’ would escape its scope This (rigid, skolem) type variable is bound by the type signature for modify :: Int -> Bar k1 v r at Foo.hs:16:11-24 Expected type: Bar k1 v r Actual type: Bar k v0 r0 ... In the expression: Bar (p - 1) $ \ y -> do { let ...; forM_ [0 .. (p - 1)] go } ...
Foo.hs:18:7: Kind incompatibility when matching types: v0 :: * -> k -> * v1 :: * -> * -> * ... When checking that ‘go’ has the inferred type ‘forall (k :: BOX) (m :: * -> *) b (v :: * -> * -> *) (v1 :: * -> * -> *). ((~) (* -> k -> *) v0 v, (~) k r0 b, (~) (* -> k -> *) v0 v1, PrimMonad m, (~) * (PrimState m) (PrimState s)) => Int -> m b’ Probable cause: the inferred type is ambiguous In the expression: do { let go i = ...; forM_ [0 .. (p - 1)] go } ... Failed, modules loaded: Bar.
}}}
These errors can be resolved by modifying the original code above in any of the following ways:
1. Remove `-XPolyKinds` from Bar.hs 2. Add an explicit kind signature to the `v :: * -> * -> *` parameter of type `Bar` 3. With `PolyKinds` in Bar but *not* Foo, uncommenting `return a` make GHC 7.8.3. compile
What I'm trying to understand is 1. Why there is different behavior from 7.8.2 to 7.8.3. There doesn't seem to be anything addressing `PolyKinds` in the [http://www.haskell.org/ghc/docs/7.8.3/html/users_guide/release-7-8-3.html release notes vs 7.8.2] . 2. In the event the above code should not compile with 7.8.3, there error message could be much clearer. The first error message above didn't help me understand that `PolyKinds` was to blame, while the second error did a better job, and the third was very clearly a `PolyKinds` issue (i.e. `kind mismatch`) 3. For the third resolution option above, I can't see any reason that adding `return a` to the inner `go` function should make the code compile while leaving it out makes the code somehow ambiguous. This, if nothing else, seems like a bug.
New description: The following code '''compiles''' with GHC 7.8.2. This code has been distilled down from a larger example where I needed `-XPolyKinds` in Bar.hs but not in Foo.hs. In addition, the `modify` function is supposed to modify a mutable `Data.Vector`, hence the inner `go` function has the intended type of `Int -> m ()`, though strictly speaking it could return any value since everything is discarded by the `forM_`. {{{ -- {-# LANGUAGE PolyKinds #-} module Foo where import Control.Monad (forM_) import Bar -- Vector signatures unsafeRead :: (Monad m) => v (PrimState m) a -> Int -> m a unsafeRead = error "type only" unsafeWrite :: (Monad m) => v (PrimState m) a -> Int -> a -> m () unsafeWrite = error "type only" modify :: Int -> Bar v r modify p = Bar (p-1) $ \y -> do let go i = do a <- unsafeRead y i unsafeWrite y i a --return a forM_ [0..(p-1)] go }}} {{{ {-# LANGUAGE RankNTypes, KindSignatures, TypeFamilies, PolyKinds #-} module Bar where type family PrimState (m :: * -> *) :: * data Bar v r = Bar Int (forall s . (Monad s) => v (PrimState s) r -> s ()) }}} In 7.8.3, this above code results in the error (with `-fprint-explicit- kinds`) {{{ Foo.hs:19:23: Couldn't match type ‘a0’ with ‘r’ ‘a0’ is untouchable inside the constraints (Monad m, (~) * (PrimState m) (PrimState s)) bound by the inferred type of go :: (Monad m, (~) * (PrimState m) (PrimState s)) => Int -> m () at Foo.hs:(18,7)-(20,23) ‘r’ is a rigid type variable bound by the type signature for modify :: Int -> Bar * v r at Foo.hs:16:11 Expected type: v0 (PrimState m) a0 Actual type: v (PrimState s) r ... In the first argument of ‘unsafeRead’, namely ‘y’ In a stmt of a 'do' block: a <- unsafeRead y i Foo.hs:20:19: Couldn't match type ‘v1’ with ‘v’ ‘v1’ is untouchable inside the constraints (Monad m, (~) * (PrimState m) (PrimState s)) bound by the inferred type of go :: (Monad m, (~) * (PrimState m) (PrimState s)) => Int -> m () at Foo.hs:(18,7)-(20,23) ‘v’ is a rigid type variable bound by the type signature for modify :: Int -> Bar * v r at Foo.hs:16:11 Expected type: v1 (PrimState m) a0 Actual type: v (PrimState s) r ... In the first argument of ‘unsafeWrite’, namely ‘y’ ... Failed, modules loaded: Bar. }}} After much digging, I found that enabling `-XPolyKinds` in Foo.hs gives a more meaningful error: {{{ Foo.hs:19:23: Could not deduce ((~) (* -> k -> *) v v0) ... Expected type: v0 (PrimState m) a0 Actual type: v (PrimState s) r ... In the first argument of ‘unsafeRead’, namely ‘y’ In a stmt of a 'do' block: a <- unsafeRead y i Foo.hs:20:19: Could not deduce ((~) (* -> k -> *) v v1) ... Expected type: v1 (PrimState m) a0 Actual type: v (PrimState s) r ... In the first argument of ‘unsafeWrite’, namely ‘y’ In a stmt of a 'do' block: unsafeWrite y i a Failed, modules loaded: Bar. }}} Adding `PolyKinds` to Foo.hs ''and'' uncommenting `return a` results in the error: {{{ Foo.hs:17:12: Couldn't match kind ‘k’ with ‘k1’ because type variable ‘k1’ would escape its scope This (rigid, skolem) type variable is bound by the type signature for modify :: Int -> Bar k1 v r at Foo.hs:16:11-24 Expected type: Bar k1 v r Actual type: Bar k v0 r0 ... In the expression: Bar (p - 1) $ \ y -> do { let ...; forM_ [0 .. (p - 1)] go } ... Foo.hs:18:7: Kind incompatibility when matching types: v0 :: * -> k -> * v1 :: * -> * -> * ... When checking that ‘go’ has the inferred type ‘forall (k :: BOX) (m :: * -> *) b (v :: * -> * -> *) (v1 :: * -> * -> *). ((~) (* -> k -> *) v0 v, (~) k r0 b, (~) (* -> k -> *) v0 v1, PrimMonad m, (~) * (PrimState m) (PrimState s)) => Int -> m b’ Probable cause: the inferred type is ambiguous In the expression: do { let go i = ...; forM_ [0 .. (p - 1)] go } ... Failed, modules loaded: Bar. }}} These errors can be resolved by modifying the original code above in any of the following ways: 1. Remove `-XPolyKinds` from Bar.hs 2. Add an explicit kind signature to the `v :: * -> * -> *` parameter of type `Bar` 3. With `PolyKinds` in Bar but *not* Foo, uncommenting `return a` make GHC 7.8.3. compile What I'm trying to understand is 1. Why there is different behavior from 7.8.2 to 7.8.3. There doesn't seem to be anything addressing `PolyKinds` in the [http://www.haskell.org/ghc/docs/7.8.3/html/users_guide/release-7-8-3.html release notes vs 7.8.2] . 2. In the event the above code should not compile with 7.8.3, there error message could be much clearer. The first error message above didn't help me understand that `PolyKinds` was to blame, while the second error did a better job, and the third was very clearly a `PolyKinds` issue (i.e. `kind mismatch`) 3. For the third resolution option above, I can't see any reason that adding `return a` to the inner `go` function should make the code compile while leaving it out makes the code somehow ambiguous. This, if nothing else, seems like a bug. -- -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/9633#comment:5 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#9633: PolyKinds in 7.8.2 vs 7.8.3 -------------------------------------+------------------------------------- Reporter: crockeea | Owner: Type: bug | Status: new Priority: normal | Milestone: Component: Compiler | Version: 7.8.3 Resolution: | Keywords: PolyKinds Operating System: | Architecture: Unknown/Multiple Unknown/Multiple | Difficulty: Unknown Type of failure: GHC | Blocked By: rejects valid program | Related Tickets: Test Case: | Blocking: | Differential Revisions: | -------------------------------------+------------------------------------- Description changed by crockeea: Old description:
The following code '''compiles''' with GHC 7.8.2.
This code has been distilled down from a larger example where I needed `-XPolyKinds` in Bar.hs but not in Foo.hs. In addition, the `modify` function is supposed to modify a mutable `Data.Vector`, hence the inner `go` function has the intended type of `Int -> m ()`, though strictly speaking it could return any value since everything is discarded by the `forM_`.
{{{ -- {-# LANGUAGE PolyKinds #-}
module Foo where
import Control.Monad (forM_) import Bar
-- Vector signatures unsafeRead :: (Monad m) => v (PrimState m) a -> Int -> m a unsafeRead = error "type only" unsafeWrite :: (Monad m) => v (PrimState m) a -> Int -> a -> m () unsafeWrite = error "type only"
modify :: Int -> Bar v r modify p = Bar (p-1) $ \y -> do let go i = do a <- unsafeRead y i unsafeWrite y i a --return a forM_ [0..(p-1)] go }}}
{{{ {-# LANGUAGE RankNTypes, KindSignatures, TypeFamilies, PolyKinds #-} module Bar where
type family PrimState (m :: * -> *) :: *
data Bar v r = Bar Int (forall s . (Monad s) => v (PrimState s) r -> s ()) }}}
In 7.8.3, this above code results in the error (with `-fprint-explicit- kinds`)
{{{ Foo.hs:19:23: Couldn't match type ‘a0’ with ‘r’ ‘a0’ is untouchable inside the constraints (Monad m, (~) * (PrimState m) (PrimState s)) bound by the inferred type of go :: (Monad m, (~) * (PrimState m) (PrimState s)) => Int -> m () at Foo.hs:(18,7)-(20,23) ‘r’ is a rigid type variable bound by the type signature for modify :: Int -> Bar * v r at Foo.hs:16:11 Expected type: v0 (PrimState m) a0 Actual type: v (PrimState s) r ... In the first argument of ‘unsafeRead’, namely ‘y’ In a stmt of a 'do' block: a <- unsafeRead y i
Foo.hs:20:19: Couldn't match type ‘v1’ with ‘v’ ‘v1’ is untouchable inside the constraints (Monad m, (~) * (PrimState m) (PrimState s)) bound by the inferred type of go :: (Monad m, (~) * (PrimState m) (PrimState s)) => Int -> m () at Foo.hs:(18,7)-(20,23) ‘v’ is a rigid type variable bound by the type signature for modify :: Int -> Bar * v r at Foo.hs:16:11 Expected type: v1 (PrimState m) a0 Actual type: v (PrimState s) r ... In the first argument of ‘unsafeWrite’, namely ‘y’ ... Failed, modules loaded: Bar. }}}
After much digging, I found that enabling `-XPolyKinds` in Foo.hs gives a more meaningful error:
{{{ Foo.hs:19:23: Could not deduce ((~) (* -> k -> *) v v0) ... Expected type: v0 (PrimState m) a0 Actual type: v (PrimState s) r ... In the first argument of ‘unsafeRead’, namely ‘y’ In a stmt of a 'do' block: a <- unsafeRead y i
Foo.hs:20:19: Could not deduce ((~) (* -> k -> *) v v1) ... Expected type: v1 (PrimState m) a0 Actual type: v (PrimState s) r ... In the first argument of ‘unsafeWrite’, namely ‘y’ In a stmt of a 'do' block: unsafeWrite y i a Failed, modules loaded: Bar. }}}
Adding `PolyKinds` to Foo.hs ''and'' uncommenting `return a` results in the error:
{{{ Foo.hs:17:12: Couldn't match kind ‘k’ with ‘k1’ because type variable ‘k1’ would escape its scope This (rigid, skolem) type variable is bound by the type signature for modify :: Int -> Bar k1 v r at Foo.hs:16:11-24 Expected type: Bar k1 v r Actual type: Bar k v0 r0 ... In the expression: Bar (p - 1) $ \ y -> do { let ...; forM_ [0 .. (p - 1)] go } ...
Foo.hs:18:7: Kind incompatibility when matching types: v0 :: * -> k -> * v1 :: * -> * -> * ... When checking that ‘go’ has the inferred type ‘forall (k :: BOX) (m :: * -> *) b (v :: * -> * -> *) (v1 :: * -> * -> *). ((~) (* -> k -> *) v0 v, (~) k r0 b, (~) (* -> k -> *) v0 v1, PrimMonad m, (~) * (PrimState m) (PrimState s)) => Int -> m b’ Probable cause: the inferred type is ambiguous In the expression: do { let go i = ...; forM_ [0 .. (p - 1)] go } ... Failed, modules loaded: Bar.
}}}
These errors can be resolved by modifying the original code above in any of the following ways:
1. Remove `-XPolyKinds` from Bar.hs 2. Add an explicit kind signature to the `v :: * -> * -> *` parameter of type `Bar` 3. With `PolyKinds` in Bar but *not* Foo, uncommenting `return a` make GHC 7.8.3. compile
What I'm trying to understand is 1. Why there is different behavior from 7.8.2 to 7.8.3. There doesn't seem to be anything addressing `PolyKinds` in the [http://www.haskell.org/ghc/docs/7.8.3/html/users_guide/release-7-8-3.html release notes vs 7.8.2] . 2. In the event the above code should not compile with 7.8.3, there error message could be much clearer. The first error message above didn't help me understand that `PolyKinds` was to blame, while the second error did a better job, and the third was very clearly a `PolyKinds` issue (i.e. `kind mismatch`) 3. For the third resolution option above, I can't see any reason that adding `return a` to the inner `go` function should make the code compile while leaving it out makes the code somehow ambiguous. This, if nothing else, seems like a bug.
New description: The following code '''compiles''' with GHC 7.8.2. This code has been distilled down from a larger example where I needed `-XPolyKinds` in Bar.hs but not in Foo.hs. In addition, the `modify` function is supposed to modify a mutable `Data.Vector`, hence the inner `go` function has the intended type of `Int -> m ()`, though strictly speaking it could return any value since everything is discarded by the `forM_`. {{{ -- {-# LANGUAGE PolyKinds #-} module Foo where import Control.Monad (forM_) import Bar -- Vector signatures unsafeRead :: (Monad m) => v (PrimState m) a -> Int -> m a unsafeRead = error "type only" unsafeWrite :: (Monad m) => v (PrimState m) a -> Int -> a -> m () unsafeWrite = error "type only" modify :: Int -> Bar v r modify p = Bar (p-1) $ \y -> do let go i = do a <- unsafeRead y i unsafeWrite y i a --return a forM_ [0..(p-1)] go }}} {{{ {-# LANGUAGE RankNTypes, KindSignatures, TypeFamilies, PolyKinds #-} module Bar where type family PrimState (m :: * -> *) :: * data Bar v r = Bar Int (forall s . (Monad s) => v (PrimState s) r -> s ()) }}} In 7.8.3, this above code results in the error (with `-fprint-explicit- kinds`) {{{ Foo.hs:19:23: Couldn't match type ‘a0’ with ‘r’ ‘a0’ is untouchable inside the constraints (Monad m, (~) * (PrimState m) (PrimState s)) bound by the inferred type of go :: (Monad m, (~) * (PrimState m) (PrimState s)) => Int -> m () at Foo.hs:(18,7)-(20,23) ‘r’ is a rigid type variable bound by the type signature for modify :: Int -> Bar * v r at Foo.hs:16:11 Expected type: v0 (PrimState m) a0 Actual type: v (PrimState s) r ... In the first argument of ‘unsafeRead’, namely ‘y’ In a stmt of a 'do' block: a <- unsafeRead y i Foo.hs:20:19: Couldn't match type ‘v1’ with ‘v’ ‘v1’ is untouchable inside the constraints (Monad m, (~) * (PrimState m) (PrimState s)) bound by the inferred type of go :: (Monad m, (~) * (PrimState m) (PrimState s)) => Int -> m () at Foo.hs:(18,7)-(20,23) ‘v’ is a rigid type variable bound by the type signature for modify :: Int -> Bar * v r at Foo.hs:16:11 Expected type: v1 (PrimState m) a0 Actual type: v (PrimState s) r ... In the first argument of ‘unsafeWrite’, namely ‘y’ ... Failed, modules loaded: Bar. }}} After much digging, I found that enabling `-XPolyKinds` in Foo.hs gives a more meaningful error: {{{ Foo.hs:19:23: Could not deduce ((~) (* -> k -> *) v v0) ... Expected type: v0 (PrimState m) a0 Actual type: v (PrimState s) r ... In the first argument of ‘unsafeRead’, namely ‘y’ In a stmt of a 'do' block: a <- unsafeRead y i Foo.hs:20:19: Could not deduce ((~) (* -> k -> *) v v1) ... Expected type: v1 (PrimState m) a0 Actual type: v (PrimState s) r ... In the first argument of ‘unsafeWrite’, namely ‘y’ In a stmt of a 'do' block: unsafeWrite y i a Failed, modules loaded: Bar. }}} Adding `PolyKinds` to Foo.hs ''and'' uncommenting `return a` results in the error: {{{ Foo.hs:17:12: Couldn't match kind ‘k’ with ‘k1’ because type variable ‘k1’ would escape its scope This (rigid, skolem) type variable is bound by the type signature for modify :: Int -> Bar k1 v r at Foo.hs:16:11-24 Expected type: Bar k1 v r Actual type: Bar k v0 r0 ... In the expression: Bar (p - 1) $ \ y -> do { let ...; forM_ [0 .. (p - 1)] go } ... Foo.hs:18:7: Kind incompatibility when matching types: v0 :: * -> k -> * v1 :: * -> * -> * ... When checking that ‘go’ has the inferred type ‘forall (k :: BOX) (m :: * -> *) b (v :: * -> * -> *) (v1 :: * -> * -> *). ((~) (* -> k -> *) v0 v, (~) k r0 b, (~) (* -> k -> *) v0 v1, Monad m, (~) * (PrimState m) (PrimState s)) => Int -> m b’ Probable cause: the inferred type is ambiguous In the expression: do { let go i = ...; forM_ [0 .. (p - 1)] go } ... Failed, modules loaded: Bar. }}} These errors can be resolved by modifying the original code above in any of the following ways: 1. Remove `-XPolyKinds` from Bar.hs 2. Add an explicit kind signature to the `v :: * -> * -> *` parameter of type `Bar` 3. With `PolyKinds` in Bar but *not* Foo, uncommenting `return a` make GHC 7.8.3. compile What I'm trying to understand is 1. Why there is different behavior from 7.8.2 to 7.8.3. There doesn't seem to be anything addressing `PolyKinds` in the [http://www.haskell.org/ghc/docs/7.8.3/html/users_guide/release-7-8-3.html release notes vs 7.8.2] . 2. In the event the above code should not compile with 7.8.3, there error message could be much clearer. The first error message above didn't help me understand that `PolyKinds` was to blame, while the second error did a better job, and the third was very clearly a `PolyKinds` issue (i.e. `kind mismatch`) 3. For the third resolution option above, I can't see any reason that adding `return a` to the inner `go` function should make the code compile while leaving it out makes the code somehow ambiguous. This, if nothing else, seems like a bug. -- -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/9633#comment:6 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#9633: PolyKinds in 7.8.2 vs 7.8.3 -------------------------------------+------------------------------------- Reporter: crockeea | Owner: Type: bug | Status: new Priority: normal | Milestone: Component: Compiler | Version: 7.8.3 Resolution: | Keywords: PolyKinds Operating System: | Architecture: Unknown/Multiple Unknown/Multiple | Difficulty: Unknown Type of failure: GHC | Blocked By: rejects valid program | Related Tickets: Test Case: | Blocking: | Differential Revisions: | -------------------------------------+------------------------------------- Comment (by simonpj): This works fine in HEAD, correct? (At least it does for me.) Simon -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/9633#comment:7 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#9633: PolyKinds in 7.8.2 vs 7.8.3 -------------------------------------+------------------------------------- Reporter: crockeea | Owner: Type: bug | Status: new Priority: normal | Milestone: Component: Compiler | Version: 7.8.3 Resolution: | Keywords: PolyKinds Operating System: | Architecture: Unknown/Multiple Unknown/Multiple | Difficulty: Unknown Type of failure: GHC | Blocked By: rejects valid program | Related Tickets: Test Case: | Blocking: | Differential Revisions: | -------------------------------------+------------------------------------- Comment (by simonpj): Here is what is happening. * Between 7.8.2 and 7.8.3, I fixed #8985. * That meant that when typechecking `go` we get a deferred equality constraint `v ~ alpha`, where `alpha` is a unification variable, but untouchable. (Before it was (wrongly) solved on the fly by unifiying an untouchable kind variable.) * Because `TypeFamilies` and `MonoLocalBinds` are not on, we try to generalise `go`. That give it a signature like `go :: (Monad m, PrimState m ~ PrimState s) => ...blah...` * Hence we get a residual unsolved implication constraint like `(Monad m, PrimState m ~ PrimState s) => v ~ alpha`. * We can't float `v ~ alpha` out of the implication because there's an equality in the "givens". * So it never gets solved. HEAD complains instead: {{{ T9633.hs:17:7: Illegal equational constraint PrimState m ~ PrimState s (Use GADTs or TypeFamilies to permit this) When checking that ‘go’ has the inferred type go :: forall (m :: * -> *). (Monad m, PrimState m ~ PrimState s) => Int -> m () }}} And when you switch on `TypeFamilies` that switches on `MonoLocalBinds` which in turn means that we don't attempt to generalise `go`, and the program compiles fine. Bottom line: I don't expect most users to make sense of the above explanation, but HEAD points you in the right direction. It's an instructive case, but I don't propose to take any new action. Simon -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/9633#comment:8 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#9633: PolyKinds in 7.8.2 vs 7.8.3 -------------------------------------+------------------------------------- Reporter: crockeea | Owner: Type: bug | Status: new Priority: normal | Milestone: Component: Compiler | Version: 7.8.3 Resolution: | Keywords: PolyKinds Operating System: | Architecture: Unknown/Multiple Unknown/Multiple | Difficulty: Unknown Type of failure: GHC | Blocked By: rejects valid program | Related Tickets: Test Case: | Blocking: | Differential Revisions: | -------------------------------------+------------------------------------- Comment (by crockeea): I verified that adding `TypeFamilies` to Foo.hs in 7.8.3 makes the original example compile fine. I'm happy with the error in HEAD, so it looks like this problem will not be an issue in 7.10. Thanks for investigating Simon! -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/9633#comment:9 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#9633: PolyKinds in 7.8.2 vs 7.8.3 -------------------------------------+------------------------------------- Reporter: crockeea | Owner: Type: bug | Status: merge Priority: normal | Milestone: Component: Compiler | Version: 7.8.3 Resolution: | Keywords: PolyKinds Operating System: | Architecture: Unknown/Multiple Unknown/Multiple | Difficulty: Unknown Type of failure: GHC | Blocked By: rejects valid program | Related Tickets: Test Case: | Blocking: | Differential Revisions: | -------------------------------------+------------------------------------- Changes (by crockeea): * status: new => merge -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/9633#comment:10 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler

#9633: PolyKinds in 7.8.2 vs 7.8.3 -------------------------------------+------------------------------------- Reporter: crockeea | Owner: Type: bug | Status: closed Priority: normal | Milestone: 7.10.1 Component: Compiler | Version: 7.8.3 Resolution: fixed | Keywords: PolyKinds Operating System: | Architecture: Unknown/Multiple Unknown/Multiple | Difficulty: Unknown Type of failure: GHC | Blocked By: rejects valid program | Related Tickets: Test Case: | Blocking: | Differential Revisions: | -------------------------------------+------------------------------------- Changes (by thoughtpolice): * status: merge => closed * resolution: => fixed * milestone: => 7.10.1 Comment: This won't be changing for 7.8, but will be in 7.10. Closing. -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/9633#comment:11 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler
participants (1)
-
GHC