GHC issueshttps://gitlab.haskell.org/ghc/ghc/-/issues2019-07-07T18:37:38Zhttps://gitlab.haskell.org/ghc/ghc/-/issues/10079Coercible solver regression: Couldn't match rep of () with Const () b2019-07-07T18:37:38ZglguyCoercible solver regression: Couldn't match rep of () with Const () bHello, I ran into what appears to be a regression in the Coercible solver since 7.8.4. This is as small as I've managed to get my example case.
```
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE FunctionalDependencies #-}
{-# LANGU...Hello, I ran into what appears to be a regression in the Coercible solver since 7.8.4. This is as small as I've managed to get my example case.
```
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE FunctionalDependencies #-}
{-# LANGUAGE FlexibleContexts #-}
module Bug where
import Control.Applicative
import Data.Coerce
broken :: Bizarre (->) w => w a b t -> ()
broken = getConst #. bazaar (Const #. const ())
class Profunctor p where
(#.) :: Coercible c b => (b -> c) -> p a b -> p a c
instance Profunctor (->) where
(#.) = (.)
class Bizarre p w | w -> p where
bazaar :: Applicative f => p a (f b) -> w a b t -> f t
```
```
Bug.hs:10:36:
Couldn't match representation of type ‘()’
with that of ‘Const () b’
Relevant role signatures: type role Const representational phantom
Relevant bindings include
broken :: w a b t -> () (bound at Bug.hs:10:1)
In the first argument of ‘bazaar’, namely ‘(Const #. const ())’
In the second argument of ‘(#.)’, namely
‘bazaar (Const #. const ())’
In the expression: getConst #. bazaar (Const #. const ())
```8.0.1Richard Eisenbergrae@richarde.devRichard Eisenbergrae@richarde.devhttps://gitlab.haskell.org/ghc/ghc/-/issues/9879Panic with partial type signatures2019-07-07T18:38:39ZKrzysztof GogolewskiPanic with partial type signaturesAttempting to check kind of type hole `_` in GHCi or putting it in a TH quotation causes a panic `rnHsTyKi HsWildcardTy`:
```
:kind _
let x = [t|_|]
```
<details><summary>Trac metadata</summary>
| Trac field | Value ...Attempting to check kind of type hole `_` in GHCi or putting it in a TH quotation causes a panic `rnHsTyKi HsWildcardTy`:
```
:kind _
let x = [t|_|]
```
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | ----------------------- |
| Version | 7.9 |
| Type | Bug |
| TypeOfFailure | OtherFailure |
| Priority | normal |
| Resolution | Unresolved |
| Component | Compiler (Type checker) |
| Test case | |
| Differential revisions | |
| BlockedBy | |
| Related | |
| Blocking | |
| CC | |
| Operating system | |
| Architecture | |
</details>
<!-- {"blocked_by":[],"summary":"Panic with partial type signatures","status":"New","operating_system":"","component":"Compiler (Type checker)","related":[],"milestone":"","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"7.9","keywords":[],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"Bug","description":"Attempting to check kind of type hole `_` in GHCi or putting it in a TH quotation causes a panic `rnHsTyKi HsWildcardTy`:\r\n\r\n{{{\r\n:kind _\r\n\r\nlet x = [t|_|]\r\n}}}","type_of_failure":"OtherFailure","blocking":[]} -->7.10.1thomaswthomaswhttps://gitlab.haskell.org/ghc/ghc/-/issues/9432IncoherentInstances are too restricted2019-07-07T18:40:25Zdanilo2IncoherentInstances are too restrictedHello! The reason behind using `IncoherentInstances`is that we want GHC to commit to a specific instance even if after instantiation of some variables, other instance could be more specific (http://www.haskell.org/ghc/docs/7.8.2/html/use...Hello! The reason behind using `IncoherentInstances`is that we want GHC to commit to a specific instance even if after instantiation of some variables, other instance could be more specific (http://www.haskell.org/ghc/docs/7.8.2/html/users_guide/type-class-extensions.html). There is one problem though. Let's consider following example (which could not make much sense, but shows the problem well):
```haskell
{-# OPTIONS_GHC -fno-warn-missing-methods #-}
{-# LANGUAGE NoMonomorphismRestriction #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE PolyKinds #-}
{-# LANGUAGE DeriveDataTypeable #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE IncoherentInstances #-}
{-# LANGUAGE ScopedTypeVariables #-}
module Main where
import Data.Typeable
--------------------------------------------------------------------------------
-- Type classes
--------------------------------------------------------------------------------
class InferType a where
inferType :: Proxy a -> Proxy a
inferType = undefined
--------------------------------------------------------------------------------
-- Proxy datatypes
--------------------------------------------------------------------------------
data Id0 = Id0 deriving (Show, Typeable)
data Id1 t1 = Id1 deriving (Show, Typeable)
data Id2 t1 t2 = Id2 deriving (Show, Typeable)
data Id3 t1 t2 t3 = Id3 deriving (Show, Typeable)
data Id4 t1 t2 t3 t4 = Id4 deriving (Show, Typeable)
data Id5 t1 t2 t3 t4 t5 = Id5 deriving (Show, Typeable)
--------------------------------------------------------------------------------
-- Instances
--------------------------------------------------------------------------------
instance InferType Int
instance (InferType m, InferType a) => InferType (m a)
instance (a~Id0) => InferType (a :: *)
instance (a~Id1) => InferType (a :: * -> *)
instance (a~Id2) => InferType (a :: * -> * -> *)
--------------------------------------------------------------------------------
-- Tests
--------------------------------------------------------------------------------
toProxy :: a -> Proxy a
toProxy _ = Proxy
--inferTypeBase :: a -> Proxy a
inferTypeBase a = inferType $ toProxy a
instance InferType Foo1
instance InferType Foo2
tm _ = 5
data Foo1 a = Foo1 a deriving (Show, Typeable)
data Foo2 a b = Foo2 a b deriving (Show, Typeable)
instance Monad Id1 -- dummy instances just for tests
instance Num Id0
main = do
print $ typeOf $ inferType $ toProxy $ (return (5))
print $ typeOf $ inferType $ toProxy $ (5)
print $ typeOf $ inferType $ toProxy $ (Foo1 (return 5))
print $ typeOf $ inferType $ toProxy $ (Foo2 (return 5) (return 5))
print "hello"
---- OUTPUT:
-- Proxy (Id1 Id0)
-- Proxy Id0
-- Proxy (Foo1 (Id1 Id0))
-- Proxy (Foo2 (Id1 Id0) (Id1 Id0))
-- "hello"
```
The idea is very simple - replace all unknown type variables with known ones. It works great, but the problem appears with the function `inferTypeBase`. It should have type of `a -> Proxy a`, but GHC claims it has got `Id0 -> Proxy Id0`. It is of course caused by enabled `-XIncoherentInstances` flag, but I think GHC should be more liberal here.
If it really cannot pick any instance (causing an error using only `OverlappingInstances`), the `IncoherentInstances` should allow it to pick matching one even if more specific could be available after instantianization. But If no error would occur while using `OverlappingInstances`, `IncoherentInstances` should not affect the way it resolves the instances. I think this would make `IncoherentInstances` much more useful than now. Maybe it would be good to just add some options to the flag?https://gitlab.haskell.org/ghc/ghc/-/issues/9318Type error reported in wrong place with repeated type family expressions2019-07-07T18:40:54ZRichard Eisenbergrae@richarde.devType error reported in wrong place with repeated type family expressionsWhen I say
```
{-# LANGUAGE TypeFamilies #-}
type family F x
type instance F Int = Bool
foo :: F Int -> ()
foo True = ()
bar :: F Int -> ()
bar 'x' = ()
```
I get
```
/Users/rae/temp/Bug.hs:7:5:
Couldn't match type ‘Char’ with ...When I say
```
{-# LANGUAGE TypeFamilies #-}
type family F x
type instance F Int = Bool
foo :: F Int -> ()
foo True = ()
bar :: F Int -> ()
bar 'x' = ()
```
I get
```
/Users/rae/temp/Bug.hs:7:5:
Couldn't match type ‘Char’ with ‘Bool’
Expected type: F Int
Actual type: Bool
In the pattern: True
In an equation for ‘foo’: foo True = ()
/Users/rae/temp/Bug.hs:10:5:
Couldn't match type ‘Bool’ with ‘Char’
Expected type: F Int
Actual type: Char
In the pattern: 'x'
In an equation for ‘bar’: bar 'x' = ()
```
The second error is most certainly correct, but the first one is most certainly not. Note that the first error is reported on the definition of `foo`, which should type-check. Also, the "Couldn't match ..." bit doesn't correspond at all with the expected/actual bit. And, the expected/actual bit shows two types that are in fact equal.
This behavior can be seen in HEAD (as of Jul. 2), 7.8.3, and 7.8.2. This is a regression from 7.6.3, where this behavior does not appear.
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | ----------------------- |
| Version | 7.8.3 |
| Type | Bug |
| TypeOfFailure | OtherFailure |
| Priority | normal |
| Resolution | Unresolved |
| Component | Compiler (Type checker) |
| Test case | |
| Differential revisions | |
| BlockedBy | |
| Related | |
| Blocking | |
| CC | |
| Operating system | |
| Architecture | |
</details>
<!-- {"blocked_by":[],"summary":"Type error reported in wrong place with repeated type family expressions","status":"New","operating_system":"","component":"Compiler (Type checker)","related":[],"milestone":"","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"7.8.3","keywords":[],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"Bug","description":"When I say\r\n\r\n{{{\r\n{-# LANGUAGE TypeFamilies #-}\r\n\r\ntype family F x\r\ntype instance F Int = Bool\r\n\r\nfoo :: F Int -> ()\r\nfoo True = ()\r\n\r\nbar :: F Int -> ()\r\nbar 'x' = ()\r\n}}}\r\n\r\nI get\r\n\r\n{{{\r\n/Users/rae/temp/Bug.hs:7:5:\r\n Couldn't match type ‘Char’ with ‘Bool’\r\n Expected type: F Int\r\n Actual type: Bool\r\n In the pattern: True\r\n In an equation for ‘foo’: foo True = ()\r\n\r\n/Users/rae/temp/Bug.hs:10:5:\r\n Couldn't match type ‘Bool’ with ‘Char’\r\n Expected type: F Int\r\n Actual type: Char\r\n In the pattern: 'x'\r\n In an equation for ‘bar’: bar 'x' = ()\r\n}}}\r\n\r\nThe second error is most certainly correct, but the first one is most certainly not. Note that the first error is reported on the definition of `foo`, which should type-check. Also, the \"Couldn't match ...\" bit doesn't correspond at all with the expected/actual bit. And, the expected/actual bit shows two types that are in fact equal.\r\n\r\nThis behavior can be seen in HEAD (as of Jul. 2), 7.8.3, and 7.8.2. This is a regression from 7.6.3, where this behavior does not appear.","type_of_failure":"OtherFailure","blocking":[]} -->7.10.1Simon Peyton JonesSimon Peyton Joneshttps://gitlab.haskell.org/ghc/ghc/-/issues/8705Type inference regression with local dictionaries2019-07-07T18:43:52ZRichard Eisenbergrae@richarde.devType inference regression with local dictionariesConsider this code:
```
{-# LANGUAGE ScopedTypeVariables, TypeOperators, DataKinds,
MultiParamTypeClasses, GADTs, ConstraintKinds #-}
import Data.Singletons.Prelude
import GHC.Exts
data Dict c where
Dict :: c => Dict c
...Consider this code:
```
{-# LANGUAGE ScopedTypeVariables, TypeOperators, DataKinds,
MultiParamTypeClasses, GADTs, ConstraintKinds #-}
import Data.Singletons.Prelude
import GHC.Exts
data Dict c where
Dict :: c => Dict c
-- A less-than-or-equal relation among naturals
class a :<=: b
sLeq :: Sing n -> Sing n2 -> Dict (n :<=: n2)
sLeq = undefined
insert_ascending :: forall n lst n1.
(lst ~ '[n1]) => Proxy n1 -> Sing n -> SList lst -> Dict (n :<=: n1)
insert_ascending _ n lst =
case lst of -- If lst has one element...
SCons h _ -> case sLeq n h of -- then check if n is <= h
Dict -> Dict -- if so, we're done
```
(adapted from [this file](https://github.com/goldfirere/singletons/blob/master/Test/InsertionSortImp.hs))
GHC 7.6.3 compiles without incident. When I run HEAD (with `-fprint-explicit-kinds`), I get
```
Ins.hs:25:17:
Could not deduce (n :<=: n1) arising from a use of ‛Dict’
from the context ((~) [*] lst ((':) * n1 ('[] *)))
bound by the type signature for
insert_ascending :: (~) [*] lst ((':) * n1 ('[] *)) =>
Proxy * n1 -> Sing * n -> SList * lst -> Dict (n :<=: n1)
at Ins.hs:(20,21)-(21,70)
or from ((~) [*] lst ((':) * n0 n2))
bound by a pattern with constructor
SCons :: forall (a0 :: BOX) (z0 :: [a0]) (n0 :: a0) (n1 :: [a0]).
(~) [a0] z0 ((':) a0 n0 n1) =>
Sing a0 n0 -> Sing [a0] n1 -> Sing [a0] z0,
in a case alternative
at Ins.hs:24:7-15
or from (n :<=: n0)
bound by a pattern with constructor
Dict :: forall (c :: Constraint). (c) => Dict c,
in a case alternative
at Ins.hs:25:9-12
Possible fix:
add (n :<=: n1) to the context of
the data constructor ‛Dict’
or the data constructor ‛SCons’
or the type signature for
insert_ascending :: (~) [*] lst ((':) * n1 ('[] *)) =>
Proxy * n1 -> Sing * n -> SList * lst -> Dict (n :<=: n1)
In the expression: Dict
In a case alternative: Dict -> Dict
In the expression: case sLeq n h of { Dict -> Dict }
```
If you stare at the type error long enough, you will see that GHC should be able to type-check this. The test case requires singletons-0.9.x, but is already much reduced.
Interestingly, if all the "givens" are put in the top-level type signature, GHC does its job well. It seems that the act of unpacking the dictionaries is causing the problem.
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | ----------------------- |
| Version | 7.7 |
| Type | Bug |
| TypeOfFailure | OtherFailure |
| Priority | normal |
| Resolution | Unresolved |
| Component | Compiler (Type checker) |
| Test case | |
| Differential revisions | |
| BlockedBy | |
| Related | |
| Blocking | |
| CC | |
| Operating system | |
| Architecture | |
</details>
<!-- {"blocked_by":[],"summary":"Type inference regression with local dictionaries","status":"New","operating_system":"","component":"Compiler (Type checker)","related":[],"milestone":"","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"7.7","keywords":[],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"Bug","description":"Consider this code:\r\n\r\n{{{\r\n{-# LANGUAGE ScopedTypeVariables, TypeOperators, DataKinds,\r\n MultiParamTypeClasses, GADTs, ConstraintKinds #-}\r\n\r\nimport Data.Singletons.Prelude\r\nimport GHC.Exts\r\n\r\ndata Dict c where\r\n Dict :: c => Dict c\r\n\r\n-- A less-than-or-equal relation among naturals\r\nclass a :<=: b\r\n\r\nsLeq :: Sing n -> Sing n2 -> Dict (n :<=: n2)\r\nsLeq = undefined\r\n\r\ninsert_ascending :: forall n lst n1.\r\n (lst ~ '[n1]) => Proxy n1 -> Sing n -> SList lst -> Dict (n :<=: n1)\r\ninsert_ascending _ n lst =\r\n case lst of -- If lst has one element...\r\n SCons h _ -> case sLeq n h of -- then check if n is <= h\r\n Dict -> Dict -- if so, we're done\r\n}}}\r\n\r\n(adapted from [https://github.com/goldfirere/singletons/blob/master/Test/InsertionSortImp.hs this file])\r\n\r\nGHC 7.6.3 compiles without incident. When I run HEAD (with `-fprint-explicit-kinds`), I get\r\n\r\n{{{\r\nIns.hs:25:17:\r\n Could not deduce (n :<=: n1) arising from a use of ‛Dict’\r\n from the context ((~) [*] lst ((':) * n1 ('[] *)))\r\n bound by the type signature for\r\n insert_ascending :: (~) [*] lst ((':) * n1 ('[] *)) =>\r\n Proxy * n1 -> Sing * n -> SList * lst -> Dict (n :<=: n1)\r\n at Ins.hs:(20,21)-(21,70)\r\n or from ((~) [*] lst ((':) * n0 n2))\r\n bound by a pattern with constructor\r\n SCons :: forall (a0 :: BOX) (z0 :: [a0]) (n0 :: a0) (n1 :: [a0]).\r\n (~) [a0] z0 ((':) a0 n0 n1) =>\r\n Sing a0 n0 -> Sing [a0] n1 -> Sing [a0] z0,\r\n in a case alternative\r\n at Ins.hs:24:7-15\r\n or from (n :<=: n0)\r\n bound by a pattern with constructor\r\n Dict :: forall (c :: Constraint). (c) => Dict c,\r\n in a case alternative\r\n at Ins.hs:25:9-12\r\n Possible fix:\r\n add (n :<=: n1) to the context of\r\n the data constructor ‛Dict’\r\n or the data constructor ‛SCons’\r\n or the type signature for\r\n insert_ascending :: (~) [*] lst ((':) * n1 ('[] *)) =>\r\n Proxy * n1 -> Sing * n -> SList * lst -> Dict (n :<=: n1)\r\n In the expression: Dict\r\n In a case alternative: Dict -> Dict\r\n In the expression: case sLeq n h of { Dict -> Dict }\r\n}}}\r\n\r\nIf you stare at the type error long enough, you will see that GHC should be able to type-check this. The test case requires singletons-0.9.x, but is already much reduced.\r\n\r\nInterestingly, if all the \"givens\" are put in the top-level type signature, GHC does its job well. It seems that the act of unpacking the dictionaries is causing the problem.","type_of_failure":"OtherFailure","blocking":[]} -->7.8.1https://gitlab.haskell.org/ghc/ghc/-/issues/8550GHC builds recursive coerctions when using recursive type families2019-07-07T18:44:32ZJoachim Breitnermail@joachim-breitner.deGHC builds recursive coerctions when using recursive type familiesConsider
```
{-# LANGUAGE TypeFamilies, GADTs, UndecidableInstances #-}
type family F a
type instance F () = F ()
data A where
A :: F () ~ () => A
x :: A
x = A
main = seq A (return ())
```
On GHC 7.6.3 it yields a context reduction s...Consider
```
{-# LANGUAGE TypeFamilies, GADTs, UndecidableInstances #-}
type family F a
type instance F () = F ()
data A where
A :: F () ~ () => A
x :: A
x = A
main = seq A (return ())
```
On GHC 7.6.3 it yields a context reduction stack overflow (despite F () \~ () being put into the “solved funeqs” list).
In HEAD, a recursive dictionary is built, but then detected:
```
[1 of 1] Compiling Foo ( Foo.hs, Foo.o )
ghc-stage2: panic! (the 'impossible' happened)
(GHC version 7.7.20131108 for x86_64-unknown-linux):
Cycle in coercion bindings
[[cobox_ayX{v} [lid]
= CO main:Foo.TFCo:R:F(){tc rob}[0] ; cobox_ayZ{v} [lid],
cobox_ayZ{v} [lid] = CO cobox_ayX{v} [lid] ; cobox_az0{v} [lid]]]
Please report this as a GHC bug: http://www.haskell.org/ghc/reportabug
```
Either this panic needs to be turned into an error, or we need to prevent recursive dictionaries for when solving funeqs (similar to how we do it for `Coercible`).8.0.1https://gitlab.haskell.org/ghc/ghc/-/issues/8129Constraint solver panic due to derived type function equality2019-07-07T18:46:21ZAdam GundryConstraint solver panic due to derived type function equality```
{-# LANGUAGE MultiParamTypeClasses, TypeFamilies #-}
{-# OPTIONS_GHC -ddump-tc-trace #-}
type family F (x :: *) :: *
class (y ~ F x) => C x y
z = () :: C x y => ()
```
causes a panic while tracing the typechecker:
```
solveNeste...```
{-# LANGUAGE MultiParamTypeClasses, TypeFamilies #-}
{-# OPTIONS_GHC -ddump-tc-trace #-}
type family F (x :: *) :: *
class (y ~ F x) => C x y
z = () :: C x y => ()
```
causes a panic while tracing the typechecker:
```
solveNestedImplications starting {
original inerts = Equalities:
Type-function equalities: [D] _ :: F x_aeH ~ y_aeI (CFunEqCan)
Dictionaries: [W] $dC_aeK :: C x_aeH y_aeI (CDictCan)
Irreds:
Insolubles = {}
Solved dicts 0
Solved funeqs 0
thinner_inerts = Equalities:ghc-stage2: panic! (the 'impossible' happened)
(GHC version 7.7.20130812 for i386-unknown-linux):
No match in record selector ctev_evar
```
If `-ddump-tc-trace` is not used, the correct constraint solving error is generated:
```
Could not deduce (C x0 y0)
arising from the ambiguity check for an expression type signature
from the context (C x y)
bound by an expression type signature: C x y => ()
```
It seems that `prepareInertsForImplications` in `TcSMonad` assumes that all the
`inert_funeqs` are givens or wanteds; if there are some deriveds, then the above panic results.
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | ----------------------- |
| Version | 7.7 |
| Type | Bug |
| TypeOfFailure | OtherFailure |
| Priority | normal |
| Resolution | Unresolved |
| Component | Compiler (Type checker) |
| Test case | |
| Differential revisions | |
| BlockedBy | |
| Related | |
| Blocking | |
| CC | |
| Operating system | |
| Architecture | |
</details>
<!-- {"blocked_by":[],"summary":"Constraint solver panic when -ddump-tc-trace is used","status":"New","operating_system":"","component":"Compiler (Type checker)","related":[],"milestone":"","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"7.7","keywords":[],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"Bug","description":"{{{\r\n{-# LANGUAGE MultiParamTypeClasses, TypeFamilies #-}\r\n{-# OPTIONS_GHC -ddump-tc-trace #-}\r\n\r\ntype family F (x :: *) :: *\r\n\r\nclass (y ~ F x) => C x y\r\n\r\nz = () :: C x y => ()\r\n}}}\r\n\r\ncauses a panic while tracing the typechecker:\r\n\r\n{{{\r\nsolveNestedImplications starting {\r\n original inerts = Equalities:\r\n Type-function equalities: [D] _ :: F x_aeH ~ y_aeI (CFunEqCan)\r\n Dictionaries: [W] $dC_aeK :: C x_aeH y_aeI (CDictCan)\r\n Irreds:\r\n Insolubles = {}\r\n Solved dicts 0\r\n Solved funeqs 0\r\n thinner_inerts = Equalities:ghc-stage2: panic! (the 'impossible' happened)\r\n (GHC version 7.7.20130812 for i386-unknown-linux):\r\n\tNo match in record selector ctev_evar\r\n}}}\r\n\r\nIf `-ddump-tc-trace` is not used, the correct constraint solving error is generated:\r\n\r\n{{{\r\n Could not deduce (C x0 y0)\r\n arising from the ambiguity check for an expression type signature\r\n from the context (C x y)\r\n bound by an expression type signature: C x y => ()\r\n}}}\r\n\r\nIt seems that `prepareInertsForImplications` in `TcSMonad` assumes that all the\r\n`inert_funeqs` are givens or wanteds; if there are some deriveds, then the above panic results.","type_of_failure":"OtherFailure","blocking":[]} -->https://gitlab.haskell.org/ghc/ghc/-/issues/8095TypeFamilies painfully slow2024-01-22T09:35:31ZMikeIzbickiTypeFamilies painfully slowI'm using the TypeFamilies extension to generate types that are quite large. GHC can handle these large types fine when they are created manually, but when type families get involved, GHC's performance dies.
**Related tickets**
* #17223...I'm using the TypeFamilies extension to generate types that are quite large. GHC can handle these large types fine when they are created manually, but when type families get involved, GHC's performance dies.
**Related tickets**
* #17223
* #22323
**Related MRs**
* !6476 Directed coercions
* !9210 Tweak isAxiom_maybe to ignore non-newtype axioms
Unlike in ticket #5321, using tail recursion does not eliminate the problem, and the order of arguments greatly affects compile time.
I've attached a file Types.hs that demonstrates the problems:
<details><summary>Types.hs</summary>
```haskell
import System.Environment
code :: Int -> String -> String -> String
code i familyTest instanceTest = concat $ map (++"\n") $
[ "{-# LANGUAGE TypeOperators,DataKinds,KindSignatures,TypeFamilies,PolyKinds,UndecidableInstances #-}"
, "import GHC.TypeLits"
, "data Nat1 = Zero | Succ Nat1"
]
++
case head familyTest of
'a' ->
[ "type family Replicate1 (n :: Nat1) (x::a) :: [a]"
, "type instance Replicate1 Zero x = '[]"
, "type instance Replicate1 (Succ n) x = x ': (Replicate1 n x)"
]
'b' ->
[ "type family Replicate1 (n :: Nat1) (x::a) :: [a]"
, "type instance Replicate1 n x = Replicate1' '[] n x "
, "type family Replicate1' (acc::[a]) (n :: Nat1) (x::a) :: [a]"
, "type instance Replicate1' acc Zero x = acc"
, "type instance Replicate1' acc (Succ n) x = Replicate1' (x ': acc) n x "
]
'c' ->
[ "type family Replicate1 (n :: Nat1) (x::a) :: [a]"
, "type instance Replicate1 n x = Replicate1' n x '[]"
, "type family Replicate1' (n :: Nat1) (x::a) (acc::[a]) :: [a]"
, "type instance Replicate1' Zero x acc = acc"
, "type instance Replicate1' (Succ n) x acc = Replicate1' n x (x ': acc)"
]
++
[ "class Class a where"
, " f :: a -> a"
, "data Data (xs::a) = X | Y"
, " deriving (Read,Show)"
, "main = print test1"
]
++
case head instanceTest of
'a' ->
[ "instance (xs ~ Replicate1 ("++mkNat1 i++") ()) => Class (Data xs) where"
, " f X = Y"
, " f Y = X"
, "test1 = f (X :: Data ( Replicate1 ("++mkNat1 i++") () ))"
]
'b' ->
[ "instance (xs ~ ("++mkList i++") ) => Class (Data xs) where"
, " f X = Y"
, " f Y = X"
, "test1 = f (X :: Data ( Replicate1 ("++mkNat1 i++") () ))"
]
'c' ->
[ "instance (xs ~ Replicate1 ("++mkNat1 i++") ()) => Class (Data xs) where"
, " f X = Y"
, " f Y = X"
, "test1 = f (X :: Data ( ("++mkList i++") ))"
]
'd' ->
[ "instance (xs ~ ("++mkList i++") ) => Class (Data xs) where"
, " f X = Y"
, " f Y = X"
, "test1 = f (X :: Data ( ("++mkList i++") ))"
]
mkList :: Int -> String
mkList 0 = " '[] "
mkList i = " () ': " ++ mkList (i-1)
mkNat1 :: Int -> String
mkNat1 0 = " Zero "
mkNat1 i = " Succ ( " ++ mkNat1 (i-1) ++ ")"
main = do
numstr : familyTest : instanceTest : xs <- getArgs
let num = read numstr :: Int
putStrLn $ code num familyTest instanceTest
```
</details>
This file generates another Haskell file which has the problems. It takes 3 flags. The first is the size of the type to generate, the second is which type family function to use, and the third is whether to call the type family or just use a manually generated type.
Here are my performance results:
Using non-tail recursion, I get these results. I have to increase the stack size based on the size of the type I want to generate.
```
$ ./Types 200 a a > test.hs && time ghc test.hs > /dev/null -fcontext-stack=250
real 0m2.973s
$ ./Types 300 a a > test.hs && time ghc test.hs > /dev/null -fcontext-stack=350
real 0m6.018s
$ ./Types 400 a a > test.hs && time ghc test.hs > /dev/null -fcontext-stack=450
real 0m9.995s
$ ./Types 500 a a > test.hs && time ghc test.hs > /dev/null -fcontext-stack=550
real 0m15.645s
```
Tail recursion generates much slower compile times for some reason, and I still need to adjust the stack size:
```
$ ./Types 200 b a > test.hs && time ghc test.hs > /dev/null -fcontext-stack=250
real 0m16.120s
```
Changing the order of arguments to the recursive type family greatly changes the run times:
```
$ ./Types 200 c a > test.hs && time ghc test.hs > /dev/null -fcontext-stack=250
real 0m6.095s
```
Without the type family, I get MUCH better performance:
```
$ ./Types 10000 a d > test.hs && time ghc test.hs > /dev/null
real 0m2.271s
```
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | ----------------------- |
| Version | 7.6.3 |
| Type | Bug |
| TypeOfFailure | OtherFailure |
| Priority | normal |
| Resolution | Unresolved |
| Component | Compiler (Type checker) |
| Test case | |
| Differential revisions | |
| BlockedBy | |
| Related | #5321 |
| Blocking | |
| CC | |
| Operating system | |
| Architecture | |
</details>
<!-- {"blocked_by":[],"summary":"TypeFamilies painfully slow","status":"New","operating_system":"","component":"Compiler (Type checker)","related":[5321],"milestone":"","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"7.6.3","keywords":[],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"Bug","description":"I'm using the TypeFamilies extension to generate types that are quite large. GHC can handle these large types fine when they are created manually, but when type families get involved, GHC's performance dies.\r\n\r\nUnlike in ticket #5321, using tail recursion does not eliminate the problem, and the order of arguments greatly affects compile time.\r\n\r\nI've attached a file Types.hs that demonstrates the problems. This file generates another Haskell file which has the problems. It takes 3 flags. The first is the size of the type to generate, the second is which type family function to use, and the third is whether to call the type family or just use a manually generated type.\r\n\r\nHere are my performance results:\r\n\r\nUsing non-tail recursion, I get these results. I have to increase the stack size based on the size of the type I want to generate.\r\n\r\n{{{\r\n$ ./Types 200 a a > test.hs && time ghc test.hs > /dev/null -fcontext-stack=250\r\nreal 0m2.973s\r\n$ ./Types 300 a a > test.hs && time ghc test.hs > /dev/null -fcontext-stack=350\r\nreal 0m6.018s\r\n$ ./Types 400 a a > test.hs && time ghc test.hs > /dev/null -fcontext-stack=450\r\nreal 0m9.995s\r\n$ ./Types 500 a a > test.hs && time ghc test.hs > /dev/null -fcontext-stack=550\r\nreal 0m15.645s\r\n}}}\r\nTail recursion generates much slower compile times for some reason, and I still need to adjust the stack size:\r\n{{{\r\n$ ./Types 200 b a > test.hs && time ghc test.hs > /dev/null -fcontext-stack=250\r\nreal 0m16.120s\r\n}}}\r\nChanging the order of arguments to the recursive type family greatly changes the run times:\r\n{{{\r\n$ ./Types 200 c a > test.hs && time ghc test.hs > /dev/null -fcontext-stack=250\r\nreal 0m6.095s\r\n}}}\r\nWithout the type family, I get MUCH better performance:\r\n{{{\r\n$ ./Types 10000 a d > test.hs && time ghc test.hs > /dev/null\r\nreal 0m2.271s\r\n}}}","type_of_failure":"OtherFailure","blocking":[]} -->https://gitlab.haskell.org/ghc/ghc/-/issues/7852panic: kindFunResult ghc-prim:GHC.Prim.*{(w) tc 34d}2019-07-07T18:47:49ZIan Lynagh <igloo@earth.li>panic: kindFunResult ghc-prim:GHC.Prim.*{(w) tc 34d}This code:
```
f :: (Num Int => Num) () => ()
f = undefined
```
make ghc panic:
```
$ ghci q.hs
GHCi, version 7.7.20130421: http://www.haskell.org/ghc/ :? for help
Loading package ghc-prim ... linking ... done.
Loading package intege...This code:
```
f :: (Num Int => Num) () => ()
f = undefined
```
make ghc panic:
```
$ ghci q.hs
GHCi, version 7.7.20130421: http://www.haskell.org/ghc/ :? for help
Loading package ghc-prim ... linking ... done.
Loading package integer-gmp ... linking ... done.
Loading package base ... linking ... done.
[1 of 1] Compiling Main ( q.hs, interpreted )
ghc-stage2: panic! (the 'impossible' happened)
(GHC version 7.7.20130421 for x86_64-unknown-linux):
kindFunResult ghc-prim:GHC.Prim.*{(w) tc 34d}
Please report this as a GHC bug: http://www.haskell.org/ghc/reportabug
>
```
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | ----------------------- |
| Version | 7.6.3 |
| Type | Bug |
| TypeOfFailure | OtherFailure |
| Priority | high |
| Resolution | Unresolved |
| Component | Compiler (Type checker) |
| Test case | |
| Differential revisions | |
| BlockedBy | |
| Related | |
| Blocking | |
| CC | |
| Operating system | |
| Architecture | |
</details>
<!-- {"blocked_by":[],"summary":"panic: kindFunResult ghc-prim:GHC.Prim.*{(w) tc 34d}","status":"New","operating_system":"","component":"Compiler (Type checker)","related":[],"milestone":"7.8.1","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"7.6.3","keywords":[],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"Bug","description":"This code:\r\n{{{\r\nf :: (Num Int => Num) () => ()\r\nf = undefined\r\n}}}\r\nmake ghc panic:\r\n{{{\r\n$ ghci q.hs\r\nGHCi, version 7.7.20130421: http://www.haskell.org/ghc/ :? for help\r\nLoading package ghc-prim ... linking ... done.\r\nLoading package integer-gmp ... linking ... done.\r\nLoading package base ... linking ... done.\r\n[1 of 1] Compiling Main ( q.hs, interpreted )\r\nghc-stage2: panic! (the 'impossible' happened)\r\n (GHC version 7.7.20130421 for x86_64-unknown-linux):\r\n kindFunResult ghc-prim:GHC.Prim.*{(w) tc 34d}\r\n\r\nPlease report this as a GHC bug: http://www.haskell.org/ghc/reportabug\r\n\r\n> \r\n}}}\r\n","type_of_failure":"OtherFailure","blocking":[]} -->7.8.1https://gitlab.haskell.org/ghc/ghc/-/issues/6147GeneralizedNewtypeDeriving should fail with data families2019-07-07T18:51:57Zrl@cse.unsw.edu.auGeneralizedNewtypeDeriving should fail with data familiesHere is an example:
```
{-# LANGUAGE GeneralizedNewtypeDeriving, TypeFamilies #-}
module Foo where
data family T a
data instance T Int = T_Int Int
class C a where
foo :: a -> T a
instance C Int where
foo = T_Int
newtype Foo = Fo...Here is an example:
```
{-# LANGUAGE GeneralizedNewtypeDeriving, TypeFamilies #-}
module Foo where
data family T a
data instance T Int = T_Int Int
class C a where
foo :: a -> T a
instance C Int where
foo = T_Int
newtype Foo = Foo Int deriving(C)
```
The `deriving(C)` clause on `Foo` should fail but instead it derives an instance which can't possible be correct since there is no corresponding `data instance T Foo`. This is closely related to #2721 (where newtype deriving was disabled in the presence of associated types) but much more difficult to test for. Probably also related to #1496.
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | ------------ |
| Version | 7.2.1 |
| Type | Bug |
| TypeOfFailure | OtherFailure |
| Priority | normal |
| Resolution | Unresolved |
| Component | Compiler |
| Test case | |
| Differential revisions | |
| BlockedBy | |
| Related | |
| Blocking | |
| CC | |
| Operating system | |
| Architecture | |
</details>
<!-- {"blocked_by":[],"summary":"GeneralizedNewtypeDeriving should fail with data families","status":"New","operating_system":"","component":"Compiler","related":[],"milestone":"","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"7.2.1","keywords":[],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"Bug","description":"Here is an example:\r\n\r\n{{{\r\n{-# LANGUAGE GeneralizedNewtypeDeriving, TypeFamilies #-}\r\nmodule Foo where\r\n\r\ndata family T a\r\ndata instance T Int = T_Int Int\r\n\r\nclass C a where\r\n foo :: a -> T a\r\n\r\ninstance C Int where\r\n foo = T_Int\r\n\r\nnewtype Foo = Foo Int deriving(C)\r\n}}}\r\n\r\nThe `deriving(C)` clause on `Foo` should fail but instead it derives an instance which can't possible be correct since there is no corresponding `data instance T Foo`. This is closely related to #2721 (where newtype deriving was disabled in the presence of associated types) but much more difficult to test for. Probably also related to #1496.","type_of_failure":"OtherFailure","blocking":[]} -->7.8.1Simon Peyton JonesSimon Peyton Joneshttps://gitlab.haskell.org/ghc/ghc/-/issues/5792PolyKinds and recompilation causes internal error2019-07-07T18:53:35ZreinerpPolyKinds and recompilation causes internal errorGiven these two files:
```
module A where
-- empty
```
and
```
{-# LANGUAGE PolyKinds, TypeFamilies, UndecidableInstances #-}
module B where
import A
data T = TT
type family Compare (m :: T) :: Ordering
type instance Compare TT = C...Given these two files:
```
module A where
-- empty
```
and
```
{-# LANGUAGE PolyKinds, TypeFamilies, UndecidableInstances #-}
module B where
import A
data T = TT
type family Compare (m :: T) :: Ordering
type instance Compare TT = Compare TT
type Compare' a = Compare a
```
We can cause an internal GHC error as follows:
```
$ rm *.o *.hi
$ ghc B.hs
[1 of 2] Compiling A ( A.hs, A.o )
[2 of 2] Compiling B ( B.hs, B.o )
$ sleep 1
$ touch B.hs
$ ghc B.hs
[2 of 2] Compiling B ( B.hs, B.o )
B.hs:11:19:
GHC internal error: `Compare' is not in scope during type checking, but it passed the renamer
tcl_env of environment: [(a9R, AThing k_a9U)]
In the type `Compare a'
In the type synonym declaration for Compare'
```
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | ----------------------- |
| Version | 7.4.1-rc1 |
| Type | Bug |
| TypeOfFailure | OtherFailure |
| Priority | normal |
| Resolution | Unresolved |
| Component | Compiler (Type checker) |
| Test case | |
| Differential revisions | |
| BlockedBy | |
| Related | |
| Blocking | |
| CC | |
| Operating system | MacOS X |
| Architecture | |
</details>
<!-- {"blocked_by":[],"summary":"PolyKinds and recompilation causes internal error","status":"New","operating_system":"MacOS X","component":"Compiler (Type checker)","related":[],"milestone":"","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"7.4.1-rc1","keywords":[],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"Bug","description":"Given these two files:\r\n{{{\r\nmodule A where\r\n-- empty\r\n}}}\r\n\r\nand\r\n\r\n{{{\r\n\r\n{-# LANGUAGE PolyKinds, TypeFamilies, UndecidableInstances #-}\r\nmodule B where\r\n\r\nimport A\r\n\r\ndata T = TT\r\n\r\ntype family Compare (m :: T) :: Ordering\r\ntype instance Compare TT = Compare TT\r\n\r\ntype Compare' a = Compare a\r\n}}}\r\n\r\nWe can cause an internal GHC error as follows:\r\n\r\n{{{\r\n$ rm *.o *.hi\r\n$ ghc B.hs\r\n[1 of 2] Compiling A ( A.hs, A.o )\r\n[2 of 2] Compiling B ( B.hs, B.o )\r\n$ sleep 1\r\n$ touch B.hs\r\n$ ghc B.hs\r\n[2 of 2] Compiling B ( B.hs, B.o )\r\n\r\nB.hs:11:19:\r\n GHC internal error: `Compare' is not in scope during type checking, but it passed the renamer\r\n tcl_env of environment: [(a9R, AThing k_a9U)]\r\n In the type `Compare a'\r\n In the type synonym declaration for Compare'\r\n}}}\r\n","type_of_failure":"OtherFailure","blocking":[]} -->7.4.2Simon Peyton JonesSimon Peyton Joneshttps://gitlab.haskell.org/ghc/ghc/-/issues/5770Non-sensical error message when compiling with PolyKinds and a type family2019-07-07T18:53:40ZRichard Eisenbergrae@richarde.devNon-sensical error message when compiling with PolyKinds and a type familyWhen I compile the following code:
```
{-# LANGUAGE TypeFamilies,
PolyKinds,
ScopedTypeVariables
#-}
convert :: a -> b
convert = undefined
type family Foo a
type instance Foo Int = Bool
bar :: forall a b c...When I compile the following code:
```
{-# LANGUAGE TypeFamilies,
PolyKinds,
ScopedTypeVariables
#-}
convert :: a -> b
convert = undefined
type family Foo a
type instance Foo Int = Bool
bar :: forall a b c dummya. (b -> c) -> ((Foo a) -> c)
bar f = (convert f :: (Foo a) -> c)
```
I get the following error message:
```
Sandbox.hs:13:34:
Kind mis-match
Expected kind `OpenKind', but `c' has kind `b'
In an expression type signature: (Foo a) -> c
In the expression: (convert f :: (Foo a) -> c)
In an equation for `bar': bar f = (convert f :: (Foo a) -> c)
```
This error message does not make sense, for 'b' isn't a kind. It is interesting to note that removing `dummya` from the list of declared type variables changes the error to a GHC panic.
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | ----------------------- |
| Version | 7.4.1-rc1 |
| Type | Bug |
| TypeOfFailure | OtherFailure |
| Priority | normal |
| Resolution | Unresolved |
| Component | Compiler (Type checker) |
| Test case | |
| Differential revisions | |
| BlockedBy | |
| Related | |
| Blocking | |
| CC | |
| Operating system | |
| Architecture | |
</details>
<!-- {"blocked_by":[],"summary":"Non-sensical error message when compiling with PolyKinds and a type family","status":"New","operating_system":"","component":"Compiler (Type checker)","related":[],"milestone":"","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"7.4.1-rc1","keywords":["PolyKinds"],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"Bug","description":"When I compile the following code:\r\n\r\n{{{\r\n{-# LANGUAGE TypeFamilies,\r\n PolyKinds,\r\n ScopedTypeVariables\r\n #-}\r\n\r\nconvert :: a -> b\r\nconvert = undefined\r\n\r\ntype family Foo a \r\ntype instance Foo Int = Bool\r\n\r\nbar :: forall a b c dummya. (b -> c) -> ((Foo a) -> c)\r\nbar f = (convert f :: (Foo a) -> c)\r\n}}}\r\n\r\nI get the following error message:\r\n\r\n{{{\r\nSandbox.hs:13:34:\r\n Kind mis-match\r\n Expected kind `OpenKind', but `c' has kind `b'\r\n In an expression type signature: (Foo a) -> c\r\n In the expression: (convert f :: (Foo a) -> c)\r\n In an equation for `bar': bar f = (convert f :: (Foo a) -> c)\r\n}}}\r\n\r\nThis error message does not make sense, for 'b' isn't a kind. It is interesting to note that removing {{{dummya}}} from the list of declared type variables changes the error to a GHC panic.","type_of_failure":"OtherFailure","blocking":[]} -->7.6.1dreixeldreixelhttps://gitlab.haskell.org/ghc/ghc/-/issues/5769Incorrect error message when compiling with PolyKinds and a type family2019-07-07T18:53:41ZRichard Eisenbergrae@richarde.devIncorrect error message when compiling with PolyKinds and a type familyWhen trying to compile
```
{-# LANGUAGE TypeFamilies,
PolyKinds,
ScopedTypeVariables
#-}
convert :: a -> b
convert = undefined
type family Foo a
bar :: forall b a. b -> (Foo a)
bar f = (convert f :: (Foo a)...When trying to compile
```
{-# LANGUAGE TypeFamilies,
PolyKinds,
ScopedTypeVariables
#-}
convert :: a -> b
convert = undefined
type family Foo a
bar :: forall b a. b -> (Foo a)
bar f = (convert f :: (Foo a))
```
I get the following error message:
```
Sandbox.hs:12:10:
Couldn't match type `Foo k a' with `Foo * b'
NB: `Foo' is a type function, and may not be injective
In the expression: (convert f :: Foo a)
In an equation for `bar': bar f = (convert f :: Foo a)
```
However, this compiles just fine without `PolyKinds`.
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | ----------------------- |
| Version | 7.4.1-rc1 |
| Type | Bug |
| TypeOfFailure | OtherFailure |
| Priority | normal |
| Resolution | Unresolved |
| Component | Compiler (Type checker) |
| Test case | |
| Differential revisions | |
| BlockedBy | |
| Related | |
| Blocking | |
| CC | |
| Operating system | |
| Architecture | |
</details>
<!-- {"blocked_by":[],"summary":"Incorrect error message when compiling with PolyKinds and a type family","status":"New","operating_system":"","component":"Compiler (Type checker)","related":[],"milestone":"","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"7.4.1-rc1","keywords":["PolyKinds"],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"Bug","description":"When trying to compile\r\n\r\n{{{\r\n{-# LANGUAGE TypeFamilies,\r\n PolyKinds,\r\n ScopedTypeVariables\r\n #-}\r\n\r\nconvert :: a -> b\r\nconvert = undefined\r\n\r\ntype family Foo a\r\n\r\nbar :: forall b a. b -> (Foo a)\r\nbar f = (convert f :: (Foo a))\r\n}}}\r\n\r\nI get the following error message:\r\n{{{\r\nSandbox.hs:12:10:\r\n Couldn't match type `Foo k a' with `Foo * b'\r\n NB: `Foo' is a type function, and may not be injective\r\n In the expression: (convert f :: Foo a)\r\n In an equation for `bar': bar f = (convert f :: Foo a)\r\n}}}\r\n\r\nHowever, this compiles just fine without {{{PolyKinds}}}.","type_of_failure":"OtherFailure","blocking":[]} -->7.6.1dreixeldreixelhttps://gitlab.haskell.org/ghc/ghc/-/issues/5007"deriving" seems to ignore class context for a type family2019-07-07T18:57:21Zjkff"deriving" seems to ignore class context for a type family```
class Foo a where
data Bar a :: *
class (Show (Bar a)) => Qux a
data (Qux a) => Xyzzy a = Xyzzy (Bar a) deriving Show
```
Here I get the following error:
```
No instance for (Show (Bar a))
arising from the 'deriving' c...```
class Foo a where
data Bar a :: *
class (Show (Bar a)) => Qux a
data (Qux a) => Xyzzy a = Xyzzy (Bar a) deriving Show
```
Here I get the following error:
```
No instance for (Show (Bar a))
arising from the 'deriving' clause of a data type declaration
Possible fix:
add an instance declaration for (Show (Bar a))
or use a standalone 'deriving instance' declaration,
so you can specify the instance context yourself
When deriving the instance for (Show (Xyzzy a))
```
Curiously, I get the same error even if I add ", Show (Bar a)" to the context of "Xyzzy".
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | ----------------------- |
| Version | 7.0.2 |
| Type | Bug |
| TypeOfFailure | OtherFailure |
| Priority | normal |
| Resolution | Unresolved |
| Component | Compiler (Type checker) |
| Test case | |
| Differential revisions | |
| BlockedBy | |
| Related | |
| Blocking | |
| CC | |
| Operating system | |
| Architecture | |
</details>
<!-- {"blocked_by":[],"summary":"\"deriving\" seems to ignore class context for a type family","status":"New","operating_system":"","component":"Compiler (Type checker)","related":[],"milestone":"","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"7.0.2","keywords":["classes,","contexts,","datatype","deriving","families,","type"],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"Bug","description":"{{{\r\nclass Foo a where\r\n data Bar a :: *\r\n\r\nclass (Show (Bar a)) => Qux a\r\ndata (Qux a) => Xyzzy a = Xyzzy (Bar a) deriving Show\r\n}}}\r\n\r\nHere I get the following error:\r\n{{{\r\n No instance for (Show (Bar a))\r\n arising from the 'deriving' clause of a data type declaration\r\n Possible fix:\r\n add an instance declaration for (Show (Bar a))\r\n or use a standalone 'deriving instance' declaration,\r\n so you can specify the instance context yourself\r\n When deriving the instance for (Show (Xyzzy a))\r\n}}}\r\n\r\nCuriously, I get the same error even if I add \", Show (Bar a)\" to the context of \"Xyzzy\".","type_of_failure":"OtherFailure","blocking":[]} -->7.2.1Simon Peyton JonesSimon Peyton Joneshttps://gitlab.haskell.org/ghc/ghc/-/issues/4801Typechecker performance regression 6.12 -> 7.0.12019-07-07T18:58:29ZSimon MarlowTypechecker performance regression 6.12 -> 7.0.1The attached module is a smaller version of the example in #4505.
With GHC 6.12.3 it takes 4s to compile (x86_64/Linux), whereas with 7.0.1 it takes 282s. HEAD seems about the same as 7.0.1.
<details><summary>Trac metadata</summary>
|...The attached module is a smaller version of the example in #4505.
With GHC 6.12.3 it takes 4s to compile (x86_64/Linux), whereas with 7.0.1 it takes 282s. HEAD seems about the same as 7.0.1.
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | ----------------------- |
| Version | 7.0.1 |
| Type | Bug |
| TypeOfFailure | OtherFailure |
| Priority | high |
| Resolution | Unresolved |
| Component | Compiler (Type checker) |
| Test case | |
| Differential revisions | |
| BlockedBy | |
| Related | |
| Blocking | |
| CC | |
| Operating system | |
| Architecture | |
</details>
<!-- {"blocked_by":[],"summary":"Typechecker performance regression 6.12 -> 7.0.1","status":"New","operating_system":"","component":"Compiler (Type checker)","related":[],"milestone":"7.0.2","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"7.0.1","keywords":[],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"Bug","description":"The attached module is a smaller version of the example in #4505.\r\n\r\nWith GHC 6.12.3 it takes 4s to compile (x86_64/Linux), whereas with 7.0.1 it takes 282s. HEAD seems about the same as 7.0.1.","type_of_failure":"OtherFailure","blocking":[]} -->7.0.2Simon Peyton JonesSimon Peyton Joneshttps://gitlab.haskell.org/ghc/ghc/-/issues/4364Template Haskell: Cycle in type synonym declarations2019-07-07T18:59:20ZIan Lynagh <igloo@earth.li>Template Haskell: Cycle in type synonym declarations`type-level-numbers-0.1` doesn't build with 7.0.1 RC 1. Here's the essence:
```
{-# LANGUAGE TemplateHaskell #-}
module Q where
data Z
type N0 = $( [t| Z |] )
type N1 = $( [t| Z |] )
```
```
$ ghc --make m.hs
[1 of 1] Compiling Q ...`type-level-numbers-0.1` doesn't build with 7.0.1 RC 1. Here's the essence:
```
{-# LANGUAGE TemplateHaskell #-}
module Q where
data Z
type N0 = $( [t| Z |] )
type N1 = $( [t| Z |] )
```
```
$ ghc --make m.hs
[1 of 1] Compiling Q ( m.hs, m.o )
m.hs:7:1:
Cycle in type synonym declarations:
m.hs:7:1-23: type N0 = $([t| Z |])
m.hs:8:1-23: type N1 = $([t| Z |])
```
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | ----------------------- |
| Version | 7.1 |
| Type | Bug |
| TypeOfFailure | OtherFailure |
| Priority | high |
| Resolution | Unresolved |
| Component | Compiler (Type checker) |
| Test case | |
| Differential revisions | |
| BlockedBy | |
| Related | |
| Blocking | |
| CC | |
| Operating system | |
| Architecture | |
</details>
<!-- {"blocked_by":[],"summary":"Template Haskell: Cycle in type synonym declarations","status":"New","operating_system":"","component":"Compiler (Type checker)","related":[],"milestone":"7.0.1","resolution":"Unresolved","owner":{"tag":"OwnedBy","contents":"simonpj"},"version":"7.1","keywords":[],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"Bug","description":"`type-level-numbers-0.1` doesn't build with 7.0.1 RC 1. Here's the essence:\r\n\r\n{{{\r\n{-# LANGUAGE TemplateHaskell #-}\r\nmodule Q where\r\n\r\ndata Z\r\n\r\ntype N0 = $( [t| Z |] )\r\ntype N1 = $( [t| Z |] )\r\n}}}\r\n\r\n{{{\r\n$ ghc --make m.hs\r\n[1 of 1] Compiling Q ( m.hs, m.o )\r\n\r\nm.hs:7:1:\r\n Cycle in type synonym declarations:\r\n m.hs:7:1-23: type N0 = $([t| Z |])\r\n m.hs:8:1-23: type N1 = $([t| Z |])\r\n}}}\r\n","type_of_failure":"OtherFailure","blocking":[]} -->7.8.1Simon Peyton JonesSimon Peyton Joneshttps://gitlab.haskell.org/ghc/ghc/-/issues/4361Typechecker regression2019-07-07T18:59:21ZIan Lynagh <igloo@earth.li>Typechecker regressionHere's the essence of the regression DoCon showed up, reported here:
http://www.haskell.org/pipermail/glasgow-haskell-bugs/2010-September/025511.html
```
{-# LANGUAGE FlexibleContexts #-}
module Pol3_ (moduloBasisx) where
class Commut...Here's the essence of the regression DoCon showed up, reported here:
http://www.haskell.org/pipermail/glasgow-haskell-bugs/2010-September/025511.html
```
{-# LANGUAGE FlexibleContexts #-}
module Pol3_ (moduloBasisx) where
class CommutativeRing a
class CommutativeRing a => LinSolvRing a
class LinSolvRing a => EuclideanRing a
instance EuclideanRing a => LinSolvRing (Pol a)
instance CommutativeRing a => CommutativeRing (Pol a)
data Pol a = MkPol
upLinSolvRing :: LinSolvRing a => a -> ()
upLinSolvRing = undefined
moduloBasisx :: (LinSolvRing (Pol a), CommutativeRing a) => Pol a -> ()
moduloBasisx p = let x = upLinSolvRing p
in ()
```
```
$ ghc --version
The Glorious Glasgow Haskell Compilation System, version 6.12.2
$ ghc --make Pol3_
[1 of 1] Compiling Pol3_ ( Pol3_.hs, Pol3_.o )
$
```
```
$ ghc --version
The Glorious Glasgow Haskell Compilation System, version 7.0.0.20100924
$ ghc --make Pol3_
[1 of 1] Compiling Pol3_ ( Pol3_.hs, Pol3_.o )
Pol3_.hs:19:26:
Could not deduce (EuclideanRing a)
from the context (LinSolvRing (Pol a), CommutativeRing a)
arising from a use of `upLinSolvRing'
Possible fix:
add (EuclideanRing a) to the context of
the type signature for `moduloBasisx'
In the expression: upLinSolvRing p
In an equation for `x': x = upLinSolvRing p
In the expression: let x = upLinSolvRing p in ()
$
```
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | ----------------------- |
| Version | 7.1 |
| Type | Bug |
| TypeOfFailure | OtherFailure |
| Priority | high |
| Resolution | Unresolved |
| Component | Compiler (Type checker) |
| Test case | |
| Differential revisions | |
| BlockedBy | |
| Related | |
| Blocking | |
| CC | |
| Operating system | |
| Architecture | |
</details>
<!-- {"blocked_by":[],"summary":"Typechecker regression","status":"New","operating_system":"","component":"Compiler (Type checker)","related":[],"milestone":"7.0.1","resolution":"Unresolved","owner":{"tag":"OwnedBy","contents":"simonpj"},"version":"7.1","keywords":[],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"Bug","description":"Here's the essence of the regression DoCon showed up, reported here:\r\nhttp://www.haskell.org/pipermail/glasgow-haskell-bugs/2010-September/025511.html\r\n\r\n{{{\r\n{-# LANGUAGE FlexibleContexts #-}\r\n\r\nmodule Pol3_ (moduloBasisx) where\r\n\r\nclass CommutativeRing a\r\nclass CommutativeRing a => LinSolvRing a\r\nclass LinSolvRing a => EuclideanRing a\r\n\r\ninstance EuclideanRing a => LinSolvRing (Pol a)\r\ninstance CommutativeRing a => CommutativeRing (Pol a)\r\n\r\ndata Pol a = MkPol\r\n\r\nupLinSolvRing :: LinSolvRing a => a -> ()\r\nupLinSolvRing = undefined\r\n\r\nmoduloBasisx :: (LinSolvRing (Pol a), CommutativeRing a) => Pol a -> ()\r\nmoduloBasisx p = let x = upLinSolvRing p\r\n in ()\r\n}}}\r\n\r\n{{{\r\n$ ghc --version\r\nThe Glorious Glasgow Haskell Compilation System, version 6.12.2\r\n$ ghc --make Pol3_\r\n[1 of 1] Compiling Pol3_ ( Pol3_.hs, Pol3_.o )\r\n$\r\n}}}\r\n\r\n{{{\r\n$ ghc --version\r\nThe Glorious Glasgow Haskell Compilation System, version 7.0.0.20100924\r\n$ ghc --make Pol3_\r\n[1 of 1] Compiling Pol3_ ( Pol3_.hs, Pol3_.o )\r\n\r\nPol3_.hs:19:26:\r\n Could not deduce (EuclideanRing a)\r\n from the context (LinSolvRing (Pol a), CommutativeRing a)\r\n arising from a use of `upLinSolvRing'\r\n Possible fix:\r\n add (EuclideanRing a) to the context of\r\n the type signature for `moduloBasisx'\r\n In the expression: upLinSolvRing p\r\n In an equation for `x': x = upLinSolvRing p\r\n In the expression: let x = upLinSolvRing p in ()\r\n$\r\n}}}\r\n","type_of_failure":"OtherFailure","blocking":[]} -->7.0.1Simon Peyton JonesSimon Peyton Joneshttps://gitlab.haskell.org/ghc/ghc/-/issues/4356type instance doesn't work when the type is (->)2019-07-07T18:59:22ZSjoerd Visschertype instance doesn't work when the type is (->)This doesn't work in 7.0.0.20100924.
It works fine in 6.12.3.
```
{-# LANGUAGE TypeFamilies #-}
type family T t :: * -> * -> *
type instance T Bool = (->)
f :: T Bool Bool Bool
f = not
```
This is the error:
```
Couldn't match typ...This doesn't work in 7.0.0.20100924.
It works fine in 6.12.3.
```
{-# LANGUAGE TypeFamilies #-}
type family T t :: * -> * -> *
type instance T Bool = (->)
f :: T Bool Bool Bool
f = not
```
This is the error:
```
Couldn't match type `T Bool' with `(->)'
Expected type: T Bool Bool Bool
Actual type: Bool -> Bool
In the expression: not
In an equation for `f': f = not
```7.0.1Simon Peyton JonesSimon Peyton Joneshttps://gitlab.haskell.org/ghc/ghc/-/issues/4355Coud not deduce (Typeable a) from context (Typeable a, …)2019-07-07T18:59:22ZmaltemCoud not deduce (Typeable a) from context (Typeable a, …)Attached is a module containing code from XMonadContrib that does not type-check anymore with ghc 7.0.1 rc1. I tried to strip the code somewhat down; at least it only depends on base and mtl. Here's the (somewhat irritating) error messag...Attached is a module containing code from XMonadContrib that does not type-check anymore with ghc 7.0.1 rc1. I tried to strip the code somewhat down; at least it only depends on base and mtl. Here's the (somewhat irritating) error message:
```
tcBug.hs:50:30:
Could not deduce (Typeable a)
from the context (Typeable a, Show ts, HList ts a, LayoutClass l a)
arising from a use of `fromMessage'
Possible fix:
add (Typeable a) to the context of the instance declaration
In a stmt of a pattern guard for
an equation for `handleMessage':
Just (Toggle t) <- fromMessage m
In an equation for `handleMessage':
handleMessage mt m
| Just (Toggle t) <- fromMessage m,
i@(Just _) <- find (transformers mt) t
= case currLayout mt of {
EL l det
-> do { l' <- fromMaybe l
`fmap`
handleMessage l (SomeMessage ReleaseResources);
.... }
where
cur = (i == currIndex mt) }
| otherwise
= case currLayout mt of {
EL l det
-> fmap (fmap (\ x -> mt {currLayout = EL x det}))
$ handleMessage l m }
In the instance declaration for `LayoutClass (MultiToggle ts l) a'
tcBug.hs:51:25:
Could not deduce (HList ts a)
from the context (Typeable a,
Show ts,
HList ts a,
LayoutClass l a,
Transformer t a)
arising from a use of `find'
Possible fix:
add (HList ts a) to the context of
the data constructor `Toggle'
or the instance declaration
In a stmt of a pattern guard for
an equation for `handleMessage':
i@(Just _) <- find (transformers mt) t
In a stmt of a pattern guard for
an equation for `handleMessage':
Just (Toggle t) <- fromMessage m
In an equation for `handleMessage':
handleMessage mt m
| Just (Toggle t) <- fromMessage m,
i@(Just _) <- find (transformers mt) t
= case currLayout mt of {
EL l det
-> do { l' <- fromMaybe l
`fmap`
handleMessage l (SomeMessage ReleaseResources);
.... }
where
cur = (i == currIndex mt) }
| otherwise
= case currLayout mt of {
EL l det
-> fmap (fmap (\ x -> mt {currLayout = EL x det}))
$ handleMessage l m }
```
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | ----------------------- |
| Version | 7.1 |
| Type | Bug |
| TypeOfFailure | OtherFailure |
| Priority | normal |
| Resolution | Unresolved |
| Component | Compiler (Type checker) |
| Test case | |
| Differential revisions | |
| BlockedBy | |
| Related | |
| Blocking | |
| CC | |
| Operating system | |
| Architecture | |
</details>
<!-- {"blocked_by":[],"summary":"Coud not deduce (Typeable a) from context (Typeable a, …)","status":"New","operating_system":"","component":"Compiler (Type checker)","related":[],"milestone":"","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"7.1","keywords":[],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"Bug","description":"Attached is a module containing code from XMonadContrib that does not type-check anymore with ghc 7.0.1 rc1. I tried to strip the code somewhat down; at least it only depends on base and mtl. Here's the (somewhat irritating) error message:\r\n\r\n{{{\r\ntcBug.hs:50:30:\r\n Could not deduce (Typeable a)\r\n from the context (Typeable a, Show ts, HList ts a, LayoutClass l a)\r\n arising from a use of `fromMessage'\r\n Possible fix:\r\n add (Typeable a) to the context of the instance declaration\r\n In a stmt of a pattern guard for\r\n an equation for `handleMessage':\r\n Just (Toggle t) <- fromMessage m\r\n In an equation for `handleMessage':\r\n handleMessage mt m\r\n | Just (Toggle t) <- fromMessage m,\r\n i@(Just _) <- find (transformers mt) t\r\n = case currLayout mt of {\r\n EL l det\r\n -> do { l' <- fromMaybe l\r\n `fmap`\r\n handleMessage l (SomeMessage ReleaseResources);\r\n .... }\r\n where\r\n cur = (i == currIndex mt) }\r\n | otherwise\r\n = case currLayout mt of {\r\n EL l det\r\n -> fmap (fmap (\\ x -> mt {currLayout = EL x det}))\r\n $ handleMessage l m }\r\n In the instance declaration for `LayoutClass (MultiToggle ts l) a'\r\n\r\ntcBug.hs:51:25:\r\n Could not deduce (HList ts a)\r\n from the context (Typeable a,\r\n Show ts,\r\n HList ts a,\r\n LayoutClass l a,\r\n Transformer t a)\r\n arising from a use of `find'\r\n Possible fix:\r\n add (HList ts a) to the context of\r\n the data constructor `Toggle'\r\n or the instance declaration\r\n In a stmt of a pattern guard for\r\n an equation for `handleMessage':\r\n i@(Just _) <- find (transformers mt) t\r\n In a stmt of a pattern guard for\r\n an equation for `handleMessage':\r\n Just (Toggle t) <- fromMessage m\r\n In an equation for `handleMessage':\r\n handleMessage mt m\r\n | Just (Toggle t) <- fromMessage m,\r\n i@(Just _) <- find (transformers mt) t\r\n = case currLayout mt of {\r\n EL l det\r\n -> do { l' <- fromMaybe l\r\n `fmap`\r\n handleMessage l (SomeMessage ReleaseResources);\r\n .... }\r\n where\r\n cur = (i == currIndex mt) }\r\n | otherwise\r\n = case currLayout mt of {\r\n EL l det\r\n -> fmap (fmap (\\ x -> mt {currLayout = EL x det}))\r\n $ handleMessage l m }\r\n}}}\r\n","type_of_failure":"OtherFailure","blocking":[]} -->7.0.1Simon Peyton JonesSimon Peyton Joneshttps://gitlab.haskell.org/ghc/ghc/-/issues/4338weird discrepancies between TFs and FDs in GHC72019-07-07T18:59:28Zillissiusweird discrepancies between TFs and FDs in GHC7I'm trying to do some seemingly equivalent code with GHC7 as of 09/19, using !TypeFamilies on the one hand and !FunctionalDependencies on the other, and my experience is that the TFs version results in some really weird-ass error message...I'm trying to do some seemingly equivalent code with GHC7 as of 09/19, using !TypeFamilies on the one hand and !FunctionalDependencies on the other, and my experience is that the TFs version results in some really weird-ass error messages from the compiler -- and a hang in one case -- whereas the FDs version works just fine. I'm not sure about the errors, though they certainly seem bizarre, but I'm pretty sure the compiler hanging is a bug. (And I assume a hang is morally equivalent to a crash, so I'm marking this as such.)
Here's the version with TFs:
```
{-# LANGUAGE MultiParamTypeClasses, TypeFamilies, FlexibleContexts #-}
class (There a ~ b, BackAgain b ~ a) => Foo a b where
type There a
type BackAgain b
there :: a -> b
back :: b -> a
tickle :: b -> b
instance Foo Char Int where
type There Char = Int
type BackAgain Int = Char
there = fromEnum
back = toEnum
tickle = (+1)
test :: (Foo a b) => a -> a
test = back . tickle . there
main :: IO ()
main = print $ test 'F'
```
and the one with FDs:
```
{-# LANGUAGE MultiParamTypeClasses, FunctionalDependencies #-}
class Bar a b | a -> b, b -> a where
there :: a -> b
back :: b -> a
tickle :: b -> b
instance Bar Char Int where
there = fromEnum
back = toEnum
tickle = (+1)
test :: (Bar a b) => a -> a
test = back . tickle . there
main :: IO ()
main = print $ test 'F'
```
Are these as functionally-equivalent as they seem, or are there some subtle differences I'm missing? (Is it possible there's some kind of configuration problem on my end?)
In any case, the result is that the TFs version gives me different errors depending on which type signatures I supply or omit, whereas the version with FDs compiles and works correctly in all cases.
The TFs version, if I supply both type signatures (as listed):
```
$ ghc Foo.hs
[1 of 1] Compiling Main ( Foo.hs, Foo.o )
Foo.hs:18:15:
Could not deduce (Foo (BackAgain (There a)) (There a))
from the context (Foo a b)
arising from a use of `tickle'
Possible fix:
add (Foo (BackAgain (There a)) (There a)) to the context of
the type signature for `test'
or add an instance declaration for
(Foo (BackAgain (There a)) (There a))
In the first argument of `(.)', namely `tickle'
In the second argument of `(.)', namely `tickle . there'
In the expression: back . tickle . there
Foo.hs:21:16:
Overlapping instances for Foo Char Int
arising from a use of `test'
Matching instances:
instance Foo Char Int -- Defined at Foo.hs:10:10-21
(The choice depends on the instantiation of `'
To pick the first instance above, use -XIncoherentInstances
when compiling the other instance declarations)
In the second argument of `($)', namely `test 'F''
In the expression: print $ test 'F'
In an equation for `main': main = print $ test 'F'
```
If I leave off the type signature for main, but not test:
```
$ ghc Foo.hs
[1 of 1] Compiling Main ( Foo.hs, Foo.o )
Foo.hs:18:15:
Could not deduce (Foo (BackAgain (There a)) (There a))
from the context (Foo a b)
arising from a use of `tickle'
Possible fix:
add (Foo (BackAgain (There a)) (There a)) to the context of
the type signature for `test'
or add an instance declaration for
(Foo (BackAgain (There a)) (There a))
In the first argument of `(.)', namely `tickle'
In the second argument of `(.)', namely `tickle . there'
In the expression: back . tickle . there
```
If I leave off the signature for test, regardless of whether I supply one for main:
```
$ ghc Foo.hs
[1 of 1] Compiling Main ( Foo.hs, Foo.o )
^C
-- a seemingly infinite loop
```
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | ----------------------- |
| Version | 6.13 |
| Type | Bug |
| TypeOfFailure | OtherFailure |
| Priority | normal |
| Resolution | Unresolved |
| Component | Compiler (Type checker) |
| Test case | |
| Differential revisions | |
| BlockedBy | |
| Related | |
| Blocking | |
| CC | |
| Operating system | |
| Architecture | |
</details>
<!-- {"blocked_by":[],"summary":"weird discrepancies between TFs and FDs in GHC7","status":"New","operating_system":"","component":"Compiler (Type checker)","related":[],"milestone":"","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"6.13","keywords":[],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"Bug","description":"I'm trying to do some seemingly equivalent code with GHC7 as of 09/19, using !TypeFamilies on the one hand and !FunctionalDependencies on the other, and my experience is that the TFs version results in some really weird-ass error messages from the compiler -- and a hang in one case -- whereas the FDs version works just fine. I'm not sure about the errors, though they certainly seem bizarre, but I'm pretty sure the compiler hanging is a bug. (And I assume a hang is morally equivalent to a crash, so I'm marking this as such.)\r\n\r\nHere's the version with TFs:\r\n\r\n{{{\r\n{-# LANGUAGE MultiParamTypeClasses, TypeFamilies, FlexibleContexts #-}\r\n\r\nclass (There a ~ b, BackAgain b ~ a) => Foo a b where\r\n type There a\r\n type BackAgain b\r\n there :: a -> b\r\n back :: b -> a\r\n tickle :: b -> b\r\n\r\ninstance Foo Char Int where\r\n type There Char = Int\r\n type BackAgain Int = Char\r\n there = fromEnum\r\n back = toEnum\r\n tickle = (+1)\r\n\r\ntest :: (Foo a b) => a -> a\r\ntest = back . tickle . there\r\n\r\nmain :: IO ()\r\nmain = print $ test 'F'\r\n}}}\r\n\r\n\r\nand the one with FDs:\r\n\r\n{{{\r\n{-# LANGUAGE MultiParamTypeClasses, FunctionalDependencies #-}\r\n\r\nclass Bar a b | a -> b, b -> a where\r\n there :: a -> b\r\n back :: b -> a\r\n tickle :: b -> b\r\n\r\ninstance Bar Char Int where\r\n there = fromEnum\r\n back = toEnum\r\n tickle = (+1)\r\n\r\ntest :: (Bar a b) => a -> a\r\ntest = back . tickle . there\r\n\r\nmain :: IO ()\r\nmain = print $ test 'F'\r\n}}}\r\n\r\nAre these as functionally-equivalent as they seem, or are there some subtle differences I'm missing? (Is it possible there's some kind of configuration problem on my end?)\r\n\r\n\r\nIn any case, the result is that the TFs version gives me different errors depending on which type signatures I supply or omit, whereas the version with FDs compiles and works correctly in all cases.\r\n\r\nThe TFs version, if I supply both type signatures (as listed):\r\n\r\n{{{\r\n$ ghc Foo.hs \r\n[1 of 1] Compiling Main ( Foo.hs, Foo.o )\r\n\r\nFoo.hs:18:15:\r\n Could not deduce (Foo (BackAgain (There a)) (There a))\r\n from the context (Foo a b)\r\n arising from a use of `tickle'\r\n Possible fix:\r\n add (Foo (BackAgain (There a)) (There a)) to the context of\r\n the type signature for `test'\r\n or add an instance declaration for\r\n (Foo (BackAgain (There a)) (There a))\r\n In the first argument of `(.)', namely `tickle'\r\n In the second argument of `(.)', namely `tickle . there'\r\n In the expression: back . tickle . there\r\n\r\nFoo.hs:21:16:\r\n Overlapping instances for Foo Char Int\r\n arising from a use of `test'\r\n Matching instances:\r\n instance Foo Char Int -- Defined at Foo.hs:10:10-21\r\n (The choice depends on the instantiation of `'\r\n To pick the first instance above, use -XIncoherentInstances\r\n when compiling the other instance declarations)\r\n In the second argument of `($)', namely `test 'F''\r\n In the expression: print $ test 'F'\r\n In an equation for `main': main = print $ test 'F'\r\n}}}\r\n\r\n\r\nIf I leave off the type signature for main, but not test:\r\n\r\n{{{\r\n$ ghc Foo.hs \r\n[1 of 1] Compiling Main ( Foo.hs, Foo.o )\r\n\r\nFoo.hs:18:15:\r\n Could not deduce (Foo (BackAgain (There a)) (There a))\r\n from the context (Foo a b)\r\n arising from a use of `tickle'\r\n Possible fix:\r\n add (Foo (BackAgain (There a)) (There a)) to the context of\r\n the type signature for `test'\r\n or add an instance declaration for\r\n (Foo (BackAgain (There a)) (There a))\r\n In the first argument of `(.)', namely `tickle'\r\n In the second argument of `(.)', namely `tickle . there'\r\n In the expression: back . tickle . there\r\n}}}\r\n\r\nIf I leave off the signature for test, regardless of whether I supply one for main:\r\n\r\n{{{\r\n$ ghc Foo.hs \r\n[1 of 1] Compiling Main ( Foo.hs, Foo.o )\r\n^C\r\n-- a seemingly infinite loop\r\n}}}\r\n\r\n","type_of_failure":"OtherFailure","blocking":[]} -->7.2.1