-
Notifications
You must be signed in to change notification settings - Fork 71
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Binding a GADT constr in let doesn't work (#548)
- Loading branch information
1 parent
4ed7157
commit ef9b718
Showing
8 changed files
with
119 additions
and
0 deletions.
There are no files selected for viewing
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
module Main where | ||
|
||
data Showable where | ||
MkShowable :: Show a => a -> Showable | ||
|
||
showShowable :: Showable -> String | ||
showShowable showable = | ||
case showable of | ||
MkShowable x -> show x | ||
|
||
main :: IO () | ||
main = putStrLn $ showShowable (MkShowable 42) |
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
module Main where | ||
|
||
data Showable where | ||
MkShowable :: Show a => a -> Showable | ||
|
||
showShowable :: Showable -> String | ||
showShowable showable = | ||
let MkShowable x = showable | ||
in show x | ||
|
||
main :: IO () | ||
main = putStrLn $ showShowable (MkShowable 42) |
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
--- | ||
title: Binding a `GADT` constructor in `let` | ||
--- | ||
|
||
In this example, we use a `let` binding to unpack the constructor of a GADT. Naively, this should work fine, because there is only one constructor. Yet GHC does not accept this code! | ||
|
||
The fix is to use pattern-matching, either with a `case` or by pattern-matching in a function argument. | ||
|
||
For more details about why this is necessary, see the [GHC user guide on ExistentialQuantification](https://downloads.haskell.org/ghc/latest/docs/users_guide/exts/existential_quantification.html#restrictions). | ||
|
||
Note: if the `TypeFamilies` extension is active, [GHC-46956](/messages/GHC-46956) is generated instead. | ||
|
||
## Message | ||
|
||
``` | ||
Let.hs:8:18: error: [GHC-25897] | ||
• Couldn't match expected type ‘p’ with actual type ‘a’ | ||
‘a’ is a rigid type variable bound by | ||
a pattern with constructor: | ||
MkShowable :: forall a. Show a => a -> Showable, | ||
in a pattern binding | ||
at Let.hs:8:7-18 | ||
‘p’ is a rigid type variable bound by | ||
the inferred type of x :: p | ||
at Let.hs:8:7-29 | ||
• In the pattern: MkShowable x | ||
In a pattern binding: MkShowable x = showable | ||
In the expression: let MkShowable x = showable in show x | ||
| | ||
8 | let MkShowable x = showable | ||
| ^ | ||
``` |
This file contains 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
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
{-# LANGUAGE TypeFamilies #-} | ||
module Main where | ||
|
||
data Showable where | ||
MkShowable :: Show a => a -> Showable | ||
|
||
showShowable :: Showable -> String | ||
showShowable showable = | ||
case showable of | ||
MkShowable x -> show x | ||
|
||
main :: IO () | ||
main = putStrLn $ showShowable (MkShowable 42) |
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
{-# LANGUAGE TypeFamilies #-} | ||
module Main where | ||
|
||
data Showable where | ||
MkShowable :: Show a => a -> Showable | ||
|
||
showShowable :: Showable -> String | ||
showShowable showable = | ||
let MkShowable x = showable | ||
in show x | ||
|
||
main :: IO () | ||
main = putStrLn $ showShowable (MkShowable 42) |
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
--- | ||
title: Binding a `GADT` constructor in `let` | ||
--- | ||
|
||
In this example, we use a `let` binding to unpack the constructor of a GADT. Naively, this should work fine, because there is only one constructor. Yet GHC does not accept this code! | ||
|
||
The fix is to use pattern-matching, either with a `case` or by pattern-matching in a function argument. | ||
|
||
For more details about why this is necessary, see the [GHC user guide on ExistentialQuantification](https://downloads.haskell.org/ghc/latest/docs/users_guide/exts/existential_quantification.html#restrictions). | ||
|
||
Note: this example generates GHC-46956 because the `TypeFamilies` extension is active. If it isn't, [GHC-25897](/messages/GHC-25897) is generated instead. | ||
|
||
## Message | ||
|
||
``` | ||
Let.hs:9:18: error: [GHC-46956] | ||
• Couldn't match expected type ‘a0’ with actual type ‘a’ | ||
because type variable ‘a’ would escape its scope | ||
This (rigid, skolem) type variable is bound by | ||
a pattern with constructor: | ||
MkShowable :: forall a. Show a => a -> Showable, | ||
in a pattern binding | ||
at Let.hs:9:7-18 | ||
• In the pattern: MkShowable x | ||
In a pattern binding: MkShowable x = showable | ||
In the expression: let MkShowable x = showable in show x | ||
| | ||
9 | let MkShowable x = showable | ||
| ^ | ||
``` |
This file contains 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