GHC issueshttps://gitlab.haskell.org/ghc/ghc/-/issues2019-07-07T18:51:01Zhttps://gitlab.haskell.org/ghc/ghc/-/issues/7171erroneous overlapping instances reported with FunDeps2019-07-07T18:51:01Zjwlatoerroneous overlapping instances reported with FunDepsWhen a superclass constraint has functional dependencies, in certain cases GHC-7.6 erroneously reports that duplicate instances are found.
file Foo.hs
```
{-# LANGUAGE FunctionalDependencies #-}
{-# LANGUAGE FlexibleInstances #-}
modu...When a superclass constraint has functional dependencies, in certain cases GHC-7.6 erroneously reports that duplicate instances are found.
file Foo.hs
```
{-# LANGUAGE FunctionalDependencies #-}
{-# LANGUAGE FlexibleInstances #-}
module Foo where
import Data.ByteString as B
import Data.Word
class Foo a b | a -> b
class (Foo a b) => Bar a b | a -> b
instance Foo [a] a
instance Bar [a] a
instance Foo ByteString Word8
instance Bar ByteString Word8
test :: Bar full item => full -> full
test inp = inp
-- this works
-- _test_x :: ByteString -> ByteString
-- _test_x = test
```
file Main.hs
```
module Main where
import Foo
import Data.ByteString
-- this works
-- test1 :: [Int] -> [Int]
-- test1 = test
-- this fails
test2 :: ByteString -> ByteString
test2 = test
```
ghc reports
```
Main.hs:12:9:
Overlapping instances for Foo ByteString GHC.Word.Word8
arising from a use of `test'
Matching instances:
instance Foo ByteString GHC.Word.Word8 -- Defined at Foo.hs:20:10
There exists a (perhaps superclass) match:
(The choice depends on the instantiation of `'
To pick the first instance above, use -XIncoherentInstances
when compiling the other instance declarations)
In the expression: test
In an equation for `test2': test2 = test
```
For this to manifest, I think that at least the following must be true:
> - a function with class constraints must be called from a separate module
> - the type class instance must be monomorphic in the fundep-to parameter
This example works in ghc-7.4.2.
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | ----------------------- |
| Version | 7.6.1-rc1 |
| Type | Bug |
| TypeOfFailure | OtherFailure |
| Priority | normal |
| Resolution | Unresolved |
| Component | Compiler (Type checker) |
| Test case | |
| Differential revisions | |
| BlockedBy | |
| Related | |
| Blocking | |
| CC | jwlato@gmail.com |
| Operating system | |
| Architecture | |
</details>
<!-- {"blocked_by":[],"summary":"erroneous overlapping instances reported with FunDeps","status":"New","operating_system":"","component":"Compiler (Type checker)","related":[],"milestone":"","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"7.6.1-rc1","keywords":["classes,","fundeps","type"],"differentials":[],"test_case":"","architecture":"","cc":["jwlato@gmail.com"],"type":"Bug","description":"When a superclass constraint has functional dependencies, in certain cases GHC-7.6 erroneously reports that duplicate instances are found.\r\n\r\nfile Foo.hs\r\n{{{\r\n{-# LANGUAGE FunctionalDependencies #-}\r\n{-# LANGUAGE FlexibleInstances #-}\r\n\r\nmodule Foo where\r\n\r\nimport Data.ByteString as B\r\nimport Data.Word\r\n\r\nclass Foo a b | a -> b\r\n\r\nclass (Foo a b) => Bar a b | a -> b\r\n\r\ninstance Foo [a] a\r\ninstance Bar [a] a\r\ninstance Foo ByteString Word8\r\ninstance Bar ByteString Word8\r\n\r\ntest :: Bar full item => full -> full\r\ntest inp = inp\r\n\r\n-- this works\r\n-- _test_x :: ByteString -> ByteString\r\n-- _test_x = test\r\n\r\n\r\n}}}\r\n\r\nfile Main.hs\r\n{{{\r\nmodule Main where\r\n\r\nimport Foo\r\nimport Data.ByteString\r\n\r\n-- this works\r\n-- test1 :: [Int] -> [Int]\r\n-- test1 = test\r\n\r\n-- this fails\r\ntest2 :: ByteString -> ByteString\r\ntest2 = test\r\n\r\n}}}\r\n\r\nghc reports\r\n\r\n{{{\r\nMain.hs:12:9:\r\n Overlapping instances for Foo ByteString GHC.Word.Word8\r\n arising from a use of `test'\r\n Matching instances:\r\n instance Foo ByteString GHC.Word.Word8 -- Defined at Foo.hs:20:10\r\n There exists a (perhaps superclass) match:\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 expression: test\r\n In an equation for `test2': test2 = test\r\n}}}\r\n\r\nFor this to manifest, I think that at least the following must be true:\r\n - a function with class constraints must be called from a separate module\r\n - the type class instance must be monomorphic in the fundep-to parameter\r\n\r\nThis example works in ghc-7.4.2.","type_of_failure":"OtherFailure","blocking":[]} -->7.6.1https://gitlab.haskell.org/ghc/ghc/-/issues/6013the 'impossible' happened2019-07-07T18:52:35Ztlvbthe 'impossible' happenedPlease forgive me if this is a duplicate or irrelevant, bug reporting and Haskell are two things I work with seldom enough that I cannot be considered good at either, but as what happened should be 'impossible' I thought I'd at least giv...Please forgive me if this is a duplicate or irrelevant, bug reporting and Haskell are two things I work with seldom enough that I cannot be considered good at either, but as what happened should be 'impossible' I thought I'd at least give you a heads up. I tried looking for similar bugs, but I do not really know what I would be looking for...
GHCi (newly opened, -v flag):
```
[leo@derse brutelift]$ ghci -v
GHCi, version 7.4.1: http://www.haskell.org/ghc/ :? for help
Glasgow Haskell Compiler, Version 7.4.1, stage 2 booted by GHC version 7.4.1
Using binary package database: /usr/lib/ghc-7.4.1/package.conf.d/package.cache
wired-in package ghc-prim mapped to ghc-prim-0.2.0.0-c2ff696e5b8ec4d4b2bc2e42085fe471
wired-in package integer-gmp mapped to integer-gmp-0.4.0.0-3cccac07aef8e27023f605c1f45bdf74
wired-in package base mapped to base-4.5.0.0-40b99d05fae6a4eea95ea69e6e0c9702
wired-in package rts mapped to builtin_rts
wired-in package template-haskell mapped to template-haskell-2.7.0.0-8c8cd20e21666657195efabced685fe1
wired-in package dph-seq not found.
wired-in package dph-par not found.
Hsc static flags: -static
Loading package ghc-prim ... linking ... done.
*** gcc:
'/usr/bin/gcc' '-fno-stack-protector' '-Wl,--hash-size=31' '-Wl,--reduce-memory-overheads' '-L/usr/lib/ghc-7.4.1/integer-gmp-0.4.0.0' '--print-file-name' 'libgmp.so'
Loading package integer-gmp ... linking ... done.
Loading package base ... linking ... done.
Prelude> :load brutelift
*** Chasing dependencies:
Chasing modules from:
Stable obj: []
Stable BCO: []
unload: retaining objs []
unload: retaining bcos []
Ready for upsweep []
Upsweep completely successful.
*** Deleting temp files:
Deleting:
*** Chasing dependencies:
Chasing modules from: *brutelift.hs
Stable obj: []
Stable BCO: []
unload: retaining objs []
unload: retaining bcos []
Ready for upsweep
[NONREC
ModSummary {
ms_hs_date = Tue Apr 17 18:10:32 CEST 2012
ms_mod = main:Main,
ms_textual_imps = [import (implicit) Prelude, import Data.List]
ms_srcimps = []
}]
*** Deleting temp files:
Deleting:
compile: input file brutelift.hs
Created temporary directory: /tmp/ghc5399_0
*** Checking old interface for main:Main:
[1 of 1] Compiling Main ( brutelift.hs, interpreted )
*** Parser:
*** Renamer/typechecker:
ghc: panic! (the 'impossible' happened)
(GHC version 7.4.1 for x86_64-unknown-linux):
nameModule show{tv abQ}
Please report this as a GHC bug: http://www.haskell.org/ghc/reportabug
>
```
brutelift.hs:
```
import Data.List
data Transfer = Load | Unload
data Action = Left Transfer Int | Right Transfer Int
data BlockDispersion = Blocks {top :: [Int]
, bottom :: [Int]
, left :: [Int]
, right :: [Int]}
deriving (Show)
data Machine = MOK BlockDispersion [Action] | MError BlockDispersion [Action] deriving (show)
rSplitAt i xs = let (a, b) = splitAt i $ reverse xs in
(reverse b, reverse a)
moveR :: Int -> ([a], [a]) -> ([a], [a])
moveR i (a, b) = let (c, d) = rSplitAt i a
in (c, d++b)
moveL :: Int -> ([a], [a]) -> ([a], [a])
moveL i (a, b) = let (c, d) = splitAt i b
in (a++c, d)
```
I am not sure what additional info to provide...
Running an Arch linux system, 8GB ram, installed ghc packgage should be as vanilla as can be...
```
[leo@derse brutelift]$ uname -a
Linux derse 3.3.1-1-ARCH #1 SMP PREEMPT Tue Apr 3 06:46:17 UTC 2012 x86_64 Intel(R) Core(TM) i5-2500K CPU @ 3.30GHz GenuineIntel GNU/Linux
```
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | ----------------------- |
| Version | 7.4.1 |
| Type | Bug |
| TypeOfFailure | GhciCrash |
| Priority | normal |
| Resolution | Unresolved |
| Component | Compiler (Type checker) |
| Test case | |
| Differential revisions | |
| BlockedBy | |
| Related | |
| Blocking | |
| CC | |
| Operating system | |
| Architecture | |
</details>
<!-- {"blocked_by":[],"summary":"the 'impossible' happened","status":"New","operating_system":"","component":"Compiler (Type checker)","related":[],"milestone":"","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"7.4.1","keywords":["checker,","impossible,","panic,","renamer","type"],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"Bug","description":"Please forgive me if this is a duplicate or irrelevant, bug reporting and Haskell are two things I work with seldom enough that I cannot be considered good at either, but as what happened should be 'impossible' I thought I'd at least give you a heads up. I tried looking for similar bugs, but I do not really know what I would be looking for...\r\n\r\nGHCi (newly opened, -v flag):\r\n{{{\r\n[leo@derse brutelift]$ ghci -v\r\nGHCi, version 7.4.1: http://www.haskell.org/ghc/ :? for help\r\nGlasgow Haskell Compiler, Version 7.4.1, stage 2 booted by GHC version 7.4.1\r\nUsing binary package database: /usr/lib/ghc-7.4.1/package.conf.d/package.cache\r\nwired-in package ghc-prim mapped to ghc-prim-0.2.0.0-c2ff696e5b8ec4d4b2bc2e42085fe471\r\nwired-in package integer-gmp mapped to integer-gmp-0.4.0.0-3cccac07aef8e27023f605c1f45bdf74\r\nwired-in package base mapped to base-4.5.0.0-40b99d05fae6a4eea95ea69e6e0c9702\r\nwired-in package rts mapped to builtin_rts\r\nwired-in package template-haskell mapped to template-haskell-2.7.0.0-8c8cd20e21666657195efabced685fe1\r\nwired-in package dph-seq not found.\r\nwired-in package dph-par not found.\r\nHsc static flags: -static\r\nLoading package ghc-prim ... linking ... done.\r\n*** gcc:\r\n'/usr/bin/gcc' '-fno-stack-protector' '-Wl,--hash-size=31' '-Wl,--reduce-memory-overheads' '-L/usr/lib/ghc-7.4.1/integer-gmp-0.4.0.0' '--print-file-name' 'libgmp.so'\r\nLoading package integer-gmp ... linking ... done.\r\nLoading package base ... linking ... done.\r\nPrelude> :load brutelift\r\n*** Chasing dependencies:\r\nChasing modules from: \r\nStable obj: []\r\nStable BCO: []\r\nunload: retaining objs []\r\nunload: retaining bcos []\r\nReady for upsweep []\r\nUpsweep completely successful.\r\n*** Deleting temp files:\r\nDeleting: \r\n*** Chasing dependencies:\r\nChasing modules from: *brutelift.hs\r\nStable obj: []\r\nStable BCO: []\r\nunload: retaining objs []\r\nunload: retaining bcos []\r\nReady for upsweep\r\n [NONREC\r\n ModSummary {\r\n ms_hs_date = Tue Apr 17 18:10:32 CEST 2012\r\n ms_mod = main:Main,\r\n ms_textual_imps = [import (implicit) Prelude, import Data.List]\r\n ms_srcimps = []\r\n }]\r\n*** Deleting temp files:\r\nDeleting: \r\ncompile: input file brutelift.hs\r\nCreated temporary directory: /tmp/ghc5399_0\r\n*** Checking old interface for main:Main:\r\n[1 of 1] Compiling Main ( brutelift.hs, interpreted )\r\n*** Parser:\r\n*** Renamer/typechecker:\r\nghc: panic! (the 'impossible' happened)\r\n (GHC version 7.4.1 for x86_64-unknown-linux):\r\n\tnameModule show{tv abQ}\r\n\r\nPlease report this as a GHC bug: http://www.haskell.org/ghc/reportabug\r\n\r\n>\r\n}}}\r\n\r\nbrutelift.hs:\r\n\r\n{{{\r\nimport Data.List\r\n\r\ndata Transfer = Load | Unload\r\ndata Action = Left Transfer Int | Right Transfer Int\r\n\r\ndata BlockDispersion = Blocks {top :: [Int]\r\n\t\t\t\t, bottom :: [Int]\r\n\t\t\t\t, left :: [Int]\r\n\t\t\t\t, right :: [Int]}\r\n\t\t\t\tderiving (Show)\r\n\r\ndata Machine = MOK BlockDispersion [Action] | MError BlockDispersion [Action] deriving (show)\r\n\r\n\r\nrSplitAt i xs = let (a, b) = splitAt i $ reverse xs in\r\n\t(reverse b, reverse a)\r\n\t\r\nmoveR :: Int -> ([a], [a]) -> ([a], [a])\r\nmoveR i (a, b) = let (c, d) = rSplitAt i a\r\n\t\t\tin (c, d++b)\r\nmoveL :: Int -> ([a], [a]) -> ([a], [a])\r\nmoveL i (a, b) = let (c, d) = splitAt i b\r\n\t\t\tin (a++c, d)\r\n}}}\r\n\r\n\r\nI am not sure what additional info to provide...\r\nRunning an Arch linux system, 8GB ram, installed ghc packgage should be as vanilla as can be...\r\n\r\n{{{\r\n[leo@derse brutelift]$ uname -a\r\nLinux derse 3.3.1-1-ARCH #1 SMP PREEMPT Tue Apr 3 06:46:17 UTC 2012 x86_64 Intel(R) Core(TM) i5-2500K CPU @ 3.30GHz GenuineIntel GNU/Linux\r\n}}}\r\n\r\n","type_of_failure":"GhciCrash","blocking":[]} -->7.6.1https://gitlab.haskell.org/ghc/ghc/-/issues/5978Type error in one function causes wrong type error report in another function...2019-07-07T18:52:44ZLemmingType error in one function causes wrong type error report in another function in the presence of functionally dependent typesWhen trying to reduce my problem in #5970 to a simple program I encountered an even more obvious bug. The problem is essentially as follows: I have
```
correct :: T
correct = ...
wrong :: T
wrong = f correct
```
where 'wrong' has a ty...When trying to reduce my problem in #5970 to a simple program I encountered an even more obvious bug. The problem is essentially as follows: I have
```
correct :: T
correct = ...
wrong :: T
wrong = f correct
```
where 'wrong' has a type error and 'correct' is type correct. If I outcomment 'wrong' then GHC correctly confirms type-correctness of 'correct', but if 'wrong' is enabled then GHC claims a type error in both 'wrong' and 'correct'.
To me it looks like the type-checker is trying to unify types across function boundaries. This would explain both non-linear growth of type-checking time and the observed effect of incorrect type errors.
See attached program for a working example.
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | ----------------------- |
| Version | 7.4.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":"Type error in one function causes wrong type error report in another function in the presence of functionally dependent types","status":"New","operating_system":"","component":"Compiler (Type checker)","related":[],"milestone":"","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"7.4.1","keywords":[],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"Bug","description":"When trying to reduce my problem in #5970 to a simple program I encountered an even more obvious bug. The problem is essentially as follows: I have\r\n{{{\r\ncorrect :: T\r\ncorrect = ...\r\n\r\nwrong :: T\r\nwrong = f correct\r\n}}}\r\nwhere 'wrong' has a type error and 'correct' is type correct. If I outcomment 'wrong' then GHC correctly confirms type-correctness of 'correct', but if 'wrong' is enabled then GHC claims a type error in both 'wrong' and 'correct'.\r\nTo me it looks like the type-checker is trying to unify types across function boundaries. This would explain both non-linear growth of type-checking time and the observed effect of incorrect type errors.\r\nSee attached program for a working example.","type_of_failure":"OtherFailure","blocking":[]} -->7.6.1https://gitlab.haskell.org/ghc/ghc/-/issues/5837Context reduction stack overflow can take very long2019-07-07T18:53:23ZdreixelContext reduction stack overflow can take very longThe following code, taken from the "Haskell Type Constraints Unleashed" paper:
```
{-# LANGUAGE TypeFamilies #-}
type family TF a :: *
type instance TF (a,b) = (TF a, TF b)
t :: (a ~ TF (a,Int)) => Int
t = undefined
```
fails almost ...The following code, taken from the "Haskell Type Constraints Unleashed" paper:
```
{-# LANGUAGE TypeFamilies #-}
type family TF a :: *
type instance TF (a,b) = (TF a, TF b)
t :: (a ~ TF (a,Int)) => Int
t = undefined
```
fails almost immediately with `Context reduction stack overflow` on GHC 7.2, but seems to loop forever with 7.4.1-rc2. Setting `-fcontext-stack` to `20` results in near immediate termination with the same error. But #5395 raised the context stack size default to `200`, which makes this code (that does not use `-XUndecidableInstances`) take "forever" to compile.
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | ----------------------- |
| Version | 7.4.1-rc2 |
| 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":"Context reduction stack overflow can take very long","status":"New","operating_system":"","component":"Compiler (Type checker)","related":[],"milestone":"","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"7.4.1-rc2","keywords":[],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"Bug","description":"The following code, taken from the \"Haskell Type Constraints Unleashed\" paper:\r\n{{{\r\n{-# LANGUAGE TypeFamilies #-}\r\n\r\ntype family TF a :: *\r\ntype instance TF (a,b) = (TF a, TF b)\r\n\r\nt :: (a ~ TF (a,Int)) => Int\r\nt = undefined\r\n}}}\r\nfails almost immediately with `Context reduction stack overflow` on GHC 7.2, but seems to loop forever with 7.4.1-rc2. Setting `-fcontext-stack` to `20` results in near immediate termination with the same error. But #5395 raised the context stack size default to `200`, which makes this code (that does not use `-XUndecidableInstances`) take \"forever\" to compile.\r\n","type_of_failure":"OtherFailure","blocking":[]} -->7.6.1Simon 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/5321Very slow constraint solving for type families2019-07-07T18:55:54ZSimon Peyton JonesVery slow constraint solving for type familiesThis post (to the ghc-users mailing list, from Gershom Bazerman) is in literate Haskell. It describes how certain performance leaks are introduced in type level programming. These leaks do not affect program runtimes, but can cause compi...This post (to the ghc-users mailing list, from Gershom Bazerman) is in literate Haskell. It describes how certain performance leaks are introduced in type level programming. These leaks do not affect program runtimes, but can cause compile times to grow drastically. They exist both with Functional Dependencies and Type Families, but are currently worse with the former, and have grown worse with the new constraint solver in GHC 7. It is intended both as a guide to those encountering these issues, and as a motivation for the GHC development team to address such issues as the constraint solver is developed and improved.
```
> {-# OPTIONS_GHC -fcontext-stack=1000 #-} {-# LANGUAGE
> FlexibleContexts, FlexibleInstances, FunctionalDependencies,
> MultiParamTypeClasses, OverlappingInstances, TypeSynonymInstances,
> TypeOperators, UndecidableInstances, TypeFamilies #-} module
> TypePerformance where
```
Our running example, for simplicity's sake, is a type-level map of a single function. For reference, here is the code for a simple value-level map of a single function.
```
> vfoo = id
> mapfoo (x : xs) = vfoo x : mapfoo xs
> mapfoo [] = []
```
Because Haskell is a lazy language, this runs in O(n) time and constant stack.
We now lift map to the type level, to operate over HLists.
First, the basic HList types
```
> infixr 3 :*
> data x :* xs = x :* xs deriving Show
> data HNil = HNil deriving Show
```
Next, a large boring HList
```
> -- Adds ten cells
> addData x = i :* i :* d :* d :* s :*
> i :* i :* d :* d :* s :*
> x
> where i = 1 :: Int
> d = 1 :: Double
> s = ""
>
> -- Has 70 cells.
> sampleData = addData $ addData $ addData $ addData $ addData $
> addData $ addData $
> HNil
```
Next, a simple polymorphic function to map
```
> class Foo x y | x -> y
> where foo :: x -> y
> foo = undefined
> instance Foo Int Double
> instance Foo Double Int
> instance Foo String String
```
Now, our map
```
> class HMapFoo1 as bs | as -> bs where
> hMapFoo1 :: as -> bs
>
> instance (Foo a b, HMapFoo1 as bs) => HMapFoo1 (a :* as) (b :* bs) where
> hMapFoo1 (x :* xs) = foo x :* hMapFoo1 xs
>
> instance HMapFoo1 HNil HNil where
> hMapFoo1 _ = HNil
```
If we enable the following line, compilation time is \~ 9 seconds.
```
> testHMapFoo1 = hMapFoo1 sampleData
```
Furthermore, playing with the size of sampleData, we see that the time spent in compilation is superlinear -- each additional cell costs a greater amount of time. This is because while Haskell is lazy at the value level, it is strict at the type level. Therefore, just as in a strict language, HMapFoo1's cost grows O(n\*\*2) because even as we induct over the as, we build up a stack of bs. Just as in a strict language, the solution is to make hMapFoo tail recursive through introducing an accumulator. This also reverses the hlist, but never mind that.
```
> class HMapFoo2 acc as bs | acc as -> bs where
> hMapFoo2 :: acc -> as -> bs
>
> instance (Foo a b, HMapFoo2 (b :* bs) as res) => HMapFoo2 bs (a :* as) res where
> hMapFoo2 acc (x :* xs) = hMapFoo2 (foo x :* acc) xs
>
> instance HMapFoo2 acc HNil acc where
> hMapFoo2 acc _ = acc
```
If we enable the following line, compilation time is a much more satisfying \~0.5s.
```
> testHMapFoo2 = hMapFoo2 HNil sampleData
```
But wait, there's trouble on the horizon! Consider the following version:
```
> class HMapFoo3 acc as bs | acc as -> bs where
> hMapFoo3 :: acc -> as -> bs
>
> instance (HMapFoo3 (b :* bs) as res, Foo a b) => HMapFoo3 bs (a :* as) res where
> hMapFoo3 acc (x :* xs) = hMapFoo3 (foo x :* acc) xs
>
> instance HMapFoo3 acc HNil acc where
> hMapFoo3 acc _ = acc
```
The only difference between hMapFoo2 and hMapFoo3 is that the order of constraints on the inductive case has been reversed, with the recursive constraint first and the immediately checkable constraint second. Now, if we enable the following line, compilation time rockets to \~6s!
```
> testHMapFoo3 = hMapFoo3 HNil sampleData
```
Slowdowns such as those described here are not a purely hypothetical issue, but have caused real problems in production code. The example given above is fairly simple. The constraints used are minimal and easily checked. In real programs, the constraints are more difficult, increasing constant factors significantly. These constant factors, combined with unexpected algorithmic slowdowns due to the type inference engine, can lead (and have lead) to compilation times of HList-style code becoming deeply unwieldy-to-unusable, and can lead (and have lead) to this occuring only well after this code has been introduced and used on smaller cases without trouble.
The constraint solver should certainly be smart enough to reduce the compile times of HMapFoo3 to those of HMapFoo2. In fact, with type families, the there is no difference (see below). Could the compiler be smart enough to do the same for HMapFoo1? I'm not sure. Certainly, it could at least knock down its own constant factors a bit, even if it can't improve the big-O performance there.
----
== Appendix: Examples with Type Families ==
As the below code demonstrates, the same issues demonstrated with Functional Dependencies also appear with Type Families, although less horribly, as their code-path seems more optimized in the current constraint solver:
```
> class TFoo x where
> type TFooFun x
> tfoo :: x -> TFooFun x
> tfoo = undefined
>
> instance TFoo Int where
> type TFooFun Int = Double
> instance TFoo Double where
> type TFooFun Double = Int
> instance TFoo String where
> type TFooFun String = String
>
> class THMapFoo1 as where
> type THMapFoo1Res as
> thMapFoo1 :: as -> THMapFoo1Res as
>
> instance (TFoo a, THMapFoo1 as) => THMapFoo1 (a :* as) where
> type THMapFoo1Res (a :* as) = TFooFun a :* THMapFoo1Res as
> thMapFoo1 (x :* xs) = tfoo x :* thMapFoo1 xs
>
> instance THMapFoo1 HNil where
> type THMapFoo1Res HNil = HNil
> thMapFoo1 _ = HNil
```
The following, when enabled, takes \~3.5s. This demonstrates that slowdown occurs with type families as well.
```
> testTHMapFoo1 = thMapFoo1 sampleData
> class THMapFoo2 acc as where
> type THMapFoo2Res acc as
> thMapFoo2 :: acc -> as -> THMapFoo2Res acc as
>
> instance (TFoo a, THMapFoo2 (TFooFun a :* acc) as) => THMapFoo2 acc (a :* as) where
> type THMapFoo2Res acc (a :* as) = THMapFoo2Res (TFooFun a :* acc) as
> thMapFoo2 acc (x :* xs) = thMapFoo2 (tfoo x :* acc) xs
>
> instance THMapFoo2 acc HNil where
> type THMapFoo2Res acc HNil = acc
> thMapFoo2 acc _ = acc
```
The following, when enabled, takes \~0.6s. This demonstrates that the tail recursive transform fixes the slowdown with type families just as with fundeps.
```
> testTHMapFoo2 = thMapFoo2 HNil sampleData
> class THMapFoo3 acc as where
> type THMapFoo3Res acc as
> thMapFoo3 :: acc -> as -> THMapFoo3Res acc as
>
> instance (THMapFoo3 (TFooFun a :* acc) as, TFoo a) => THMapFoo3 acc (a :* as) where
> type THMapFoo3Res acc (a :* as) = THMapFoo3Res (TFooFun a :* acc) as
> thMapFoo3 acc (x :* xs) = thMapFoo3 (tfoo x :* acc) xs
>
> instance THMapFoo3 acc HNil where
> type THMapFoo3Res acc HNil = acc
> thMapFoo3 acc _ = acc
```
The following, when enabled, also takes \~0.6s. This demonstrates that, unlike the fundep case, the order of type class constraints does not, in this instance, affect the performance of type families.
```
> testTHMapFoo3 = thMapFoo3 HNil sampleData
```
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | ------------------------------------------ |
| Version | 7.0.3 |
| Type | Bug |
| TypeOfFailure | OtherFailure |
| Priority | normal |
| Resolution | Unresolved |
| Component | Compiler (Type checker) |
| Test case | |
| Differential revisions | |
| BlockedBy | |
| Related | |
| Blocking | |
| CC | dimitris@microsoft.com, gershomb@gmail.com |
| Operating system | |
| Architecture | |
</details>
<!-- {"blocked_by":[],"summary":"Very slow constraint solving for type families","status":"New","operating_system":"","component":"Compiler (Type checker)","related":[],"milestone":"","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"7.0.3","keywords":[],"differentials":[],"test_case":"","architecture":"","cc":["dimitris@microsoft.com","gershomb@gmail.com"],"type":"Bug","description":"This post (to the ghc-users mailing list, from Gershom Bazerman) is in literate Haskell. It describes how certain performance leaks are introduced in type level programming. These leaks do not affect program runtimes, but can cause compile times to grow drastically. They exist both with Functional Dependencies and Type Families, but are currently worse with the former, and have grown worse with the new constraint solver in GHC 7. It is intended both as a guide to those encountering these issues, and as a motivation for the GHC development team to address such issues as the constraint solver is developed and improved. \r\n\r\n{{{\r\n> {-# OPTIONS_GHC -fcontext-stack=1000 #-} {-# LANGUAGE \r\n> FlexibleContexts, FlexibleInstances, FunctionalDependencies, \r\n> MultiParamTypeClasses, OverlappingInstances, TypeSynonymInstances, \r\n> TypeOperators, UndecidableInstances, TypeFamilies #-} module \r\n> TypePerformance where\r\n}}}\r\nOur running example, for simplicity's sake, is a type-level map of a single function. For reference, here is the code for a simple value-level map of a single function. \r\n{{{\r\n> vfoo = id\r\n> mapfoo (x : xs) = vfoo x : mapfoo xs\r\n> mapfoo [] = []\r\n}}}\r\nBecause Haskell is a lazy language, this runs in O(n) time and constant stack. \r\n\r\nWe now lift map to the type level, to operate over HLists. \r\n\r\nFirst, the basic HList types \r\n{{{\r\n> infixr 3 :*\r\n> data x :* xs = x :* xs deriving Show\r\n> data HNil = HNil deriving Show\r\n}}}\r\nNext, a large boring HList \r\n{{{\r\n> -- Adds ten cells\r\n> addData x = i :* i :* d :* d :* s :* \r\n> i :* i :* d :* d :* s :* \r\n> x \r\n> where i = 1 :: Int \r\n> d = 1 :: Double \r\n> s = \"\" \r\n> \r\n> -- Has 70 cells. \r\n> sampleData = addData $ addData $ addData $ addData $ addData $ \r\n> addData $ addData $ \r\n> HNil\r\n}}}\r\nNext, a simple polymorphic function to map \r\n{{{\r\n> class Foo x y | x -> y \r\n> where foo :: x -> y \r\n> foo = undefined\r\n\r\n> instance Foo Int Double\r\n> instance Foo Double Int\r\n> instance Foo String String\r\n}}}\r\nNow, our map \r\n{{{\r\n> class HMapFoo1 as bs | as -> bs where \r\n> hMapFoo1 :: as -> bs\r\n> \r\n> instance (Foo a b, HMapFoo1 as bs) => HMapFoo1 (a :* as) (b :* bs) where \r\n> hMapFoo1 (x :* xs) = foo x :* hMapFoo1 xs\r\n> \r\n> instance HMapFoo1 HNil HNil where \r\n> hMapFoo1 _ = HNil\r\n}}}\r\nIf we enable the following line, compilation time is ~ 9 seconds. \r\n{{{\r\n > testHMapFoo1 = hMapFoo1 sampleData \r\n}}}\r\nFurthermore, playing with the size of sampleData, we see that the time spent in compilation is superlinear -- each additional cell costs a greater amount of time. This is because while Haskell is lazy at the value level, it is strict at the type level. Therefore, just as in a strict language, HMapFoo1's cost grows O(n**2) because even as we induct over the as, we build up a stack of bs. Just as in a strict language, the solution is to make hMapFoo tail recursive through introducing an accumulator. This also reverses the hlist, but never mind that. \r\n{{{\r\n> class HMapFoo2 acc as bs | acc as -> bs where \r\n> hMapFoo2 :: acc -> as -> bs\r\n> \r\n> instance (Foo a b, HMapFoo2 (b :* bs) as res) => HMapFoo2 bs (a :* as) res where \r\n> hMapFoo2 acc (x :* xs) = hMapFoo2 (foo x :* acc) xs\r\n> \r\n> instance HMapFoo2 acc HNil acc where \r\n> hMapFoo2 acc _ = acc\r\n}}}\r\nIf we enable the following line, compilation time is a much more satisfying ~0.5s. \r\n{{{\r\n > testHMapFoo2 = hMapFoo2 HNil sampleData \r\n}}}\r\nBut wait, there's trouble on the horizon! Consider the following version: \r\n{{{\r\n> class HMapFoo3 acc as bs | acc as -> bs where \r\n> hMapFoo3 :: acc -> as -> bs\r\n> \r\n> instance (HMapFoo3 (b :* bs) as res, Foo a b) => HMapFoo3 bs (a :* as) res where \r\n> hMapFoo3 acc (x :* xs) = hMapFoo3 (foo x :* acc) xs\r\n> \r\n> instance HMapFoo3 acc HNil acc where \r\n> hMapFoo3 acc _ = acc\r\n}}}\r\nThe only difference between hMapFoo2 and hMapFoo3 is that the order of constraints on the inductive case has been reversed, with the recursive constraint first and the immediately checkable constraint second. Now, if we enable the following line, compilation time rockets to ~6s! \r\n{{{\r\n > testHMapFoo3 = hMapFoo3 HNil sampleData \r\n}}}\r\nSlowdowns such as those described here are not a purely hypothetical issue, but have caused real problems in production code. The example given above is fairly simple. The constraints used are minimal and easily checked. In real programs, the constraints are more difficult, increasing constant factors significantly. These constant factors, combined with unexpected algorithmic slowdowns due to the type inference engine, can lead (and have lead) to compilation times of HList-style code becoming deeply unwieldy-to-unusable, and can lead (and have lead) to this occuring only well after this code has been introduced and used on smaller cases without trouble. \r\n\r\nThe constraint solver should certainly be smart enough to reduce the compile times of HMapFoo3 to those of HMapFoo2. In fact, with type families, the there is no difference (see below). Could the compiler be smart enough to do the same for HMapFoo1? I'm not sure. Certainly, it could at least knock down its own constant factors a bit, even if it can't improve the big-O performance there. \r\n\r\n----\r\n== Appendix: Examples with Type Families ==\r\n\r\nAs the below code demonstrates, the same issues demonstrated with Functional Dependencies also appear with Type Families, although less horribly, as their code-path seems more optimized in the current constraint solver: \r\n{{{\r\n> class TFoo x where \r\n> type TFooFun x \r\n> tfoo :: x -> TFooFun x \r\n> tfoo = undefined\r\n> \r\n> instance TFoo Int where \r\n> type TFooFun Int = Double\r\n> instance TFoo Double where \r\n> type TFooFun Double = Int\r\n> instance TFoo String where \r\n> type TFooFun String = String\r\n> \r\n> class THMapFoo1 as where \r\n> type THMapFoo1Res as \r\n> thMapFoo1 :: as -> THMapFoo1Res as\r\n> \r\n> instance (TFoo a, THMapFoo1 as) => THMapFoo1 (a :* as) where \r\n> type THMapFoo1Res (a :* as) = TFooFun a :* THMapFoo1Res as \r\n> thMapFoo1 (x :* xs) = tfoo x :* thMapFoo1 xs\r\n> \r\n> instance THMapFoo1 HNil where \r\n> type THMapFoo1Res HNil = HNil \r\n> thMapFoo1 _ = HNil\r\n}}}\r\nThe following, when enabled, takes ~3.5s. This demonstrates that slowdown occurs with type families as well. \r\n{{{\r\n > testTHMapFoo1 = thMapFoo1 sampleData \r\n\r\n> class THMapFoo2 acc as where \r\n> type THMapFoo2Res acc as \r\n> thMapFoo2 :: acc -> as -> THMapFoo2Res acc as\r\n> \r\n> instance (TFoo a, THMapFoo2 (TFooFun a :* acc) as) => THMapFoo2 acc (a :* as) where \r\n> type THMapFoo2Res acc (a :* as) = THMapFoo2Res (TFooFun a :* acc) as \r\n> thMapFoo2 acc (x :* xs) = thMapFoo2 (tfoo x :* acc) xs\r\n> \r\n> instance THMapFoo2 acc HNil where \r\n> type THMapFoo2Res acc HNil = acc \r\n> thMapFoo2 acc _ = acc\r\n}}}\r\nThe following, when enabled, takes ~0.6s. This demonstrates that the tail recursive transform fixes the slowdown with type families just as with fundeps. \r\n{{{\r\n > testTHMapFoo2 = thMapFoo2 HNil sampleData \r\n\r\n> class THMapFoo3 acc as where \r\n> type THMapFoo3Res acc as \r\n> thMapFoo3 :: acc -> as -> THMapFoo3Res acc as\r\n> \r\n> instance (THMapFoo3 (TFooFun a :* acc) as, TFoo a) => THMapFoo3 acc (a :* as) where \r\n> type THMapFoo3Res acc (a :* as) = THMapFoo3Res (TFooFun a :* acc) as \r\n> thMapFoo3 acc (x :* xs) = thMapFoo3 (tfoo x :* acc) xs\r\n> \r\n> instance THMapFoo3 acc HNil where \r\n> type THMapFoo3Res acc HNil = acc \r\n> thMapFoo3 acc _ = acc\r\n}}}\r\nThe following, when enabled, also takes ~0.6s. This demonstrates that, unlike the fundep case, the order of type class constraints does not, in this instance, affect the performance of type families. \r\n{{{\r\n > testTHMapFoo3 = thMapFoo3 HNil sampleData \r\n}}}\r\n\r\n","type_of_failure":"OtherFailure","blocking":[]} -->7.6.1https://gitlab.haskell.org/ghc/ghc/-/issues/3108Do a better job of solving recursive type-class constraints with functional d...2019-07-07T19:05:21ZSimon Peyton JonesDo a better job of solving recursive type-class constraints with functional dependenciesThis ticket is just to track this interesting thread on the Haskell list, concerning recursive type-class constraints:
http://www.haskell.org/pipermail/haskell/2009-March/021115.html.
We might want to get back to this when the new constr...This ticket is just to track this interesting thread on the Haskell list, concerning recursive type-class constraints:
http://www.haskell.org/pipermail/haskell/2009-March/021115.html.
We might want to get back to this when the new constraint solver is in place.
The question concerns the interaction of solving recursive type-class constraints, where it is important to aggressively apply functional dependencies. Here's Tom Schrijvers's analysis of Ralf's example:
"The cyclic dictionaries approach is a bit fragile. The problem appears to
be here that GHC alternates exhaustive phases of constraint reduction and
functional dependency improvement. The problem is that in your example you
need both for detecting a cycle.
This can happen:
```
C1 Int
==> 3rd C1 inst
C2 Int y, C1 (y,Bool)
==> 1st C1 inst
C2 Int y, C1 y, C1 Bool
==> 2nd C1 inst
C2 Int y, C1 y
==> 3rd C1 inst
C2 Int y, C2 y z, C1 (z,Bool)
==>
...
```
where all the constraint are different because fresh variables are
introduced.
What you want to happen is:
```
C1 Int
==> 3rd C1 inst
C2 Int y, C1 (y,Bool)
==> 1st C1 inst
C2 Int y, C1 y, C1 Bool
==> 2nd C1 inst
C2 Int y, C1 y
==> C2 FD improvement {Int/y} <<<<
C2 Int Int, C1 Int
==> C1 Int cycle detected
C2 Int Int
==> C2 1st instance
{}
```
It seems that you want improvement to happen at a higher priority than GHC
does now."
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | ----------------------- |
| Version | 6.10.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":"Do a better job of solving recursive type-class constraints with functional dependencies","status":"New","operating_system":"","component":"Compiler (Type checker)","related":[],"milestone":"6.12 branch","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"6.10.1","keywords":[],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"Bug","description":"This ticket is just to track this interesting thread on the Haskell list, concerning recursive type-class constraints:\r\nhttp://www.haskell.org/pipermail/haskell/2009-March/021115.html.\r\nWe might want to get back to this when the new constraint solver is in place.\r\n\r\nThe question concerns the interaction of solving recursive type-class constraints, where it is important to aggressively apply functional dependencies. Here's Tom Schrijvers's analysis of Ralf's example:\r\n\r\n\"The cyclic dictionaries approach is a bit fragile. The problem appears to\r\nbe here that GHC alternates exhaustive phases of constraint reduction and\r\nfunctional dependency improvement. The problem is that in your example you\r\nneed both for detecting a cycle.\r\n\r\nThis can happen:\r\n{{{\r\n C1 Int\r\n ==> 3rd C1 inst\r\n C2 Int y, C1 (y,Bool)\r\n ==> 1st C1 inst\r\n C2 Int y, C1 y, C1 Bool\r\n ==> 2nd C1 inst\r\n C2 Int y, C1 y\r\n ==> 3rd C1 inst\r\n C2 Int y, C2 y z, C1 (z,Bool)\r\n ==>\r\n ...\r\n}}}\r\nwhere all the constraint are different because fresh variables are\r\nintroduced.\r\n\r\nWhat you want to happen is:\r\n{{{\r\n C1 Int\r\n ==> 3rd C1 inst\r\n C2 Int y, C1 (y,Bool)\r\n ==> 1st C1 inst\r\n C2 Int y, C1 y, C1 Bool\r\n ==> 2nd C1 inst\r\n C2 Int y, C1 y\r\n ==> C2 FD improvement {Int/y} <<<<\r\n C2 Int Int, C1 Int\r\n ==> C1 Int cycle detected\r\n C2 Int Int\r\n ==> C2 1st instance\r\n {}\r\n}}}\r\nIt seems that you want improvement to happen at a higher priority than GHC\r\ndoes now.\"\r\n","type_of_failure":"OtherFailure","blocking":[]} -->7.6.1https://gitlab.haskell.org/ghc/ghc/-/issues/2534Odd probable cause given by type checker2019-07-07T19:08:10Zred5_2@hotmail.comOdd probable cause given by type checkerIn the following code, a function has been applied to zero arguments, which the type checker suggests is too many.
```
Prelude> foldr (>>=) [] []
<interactive>:1:6:
Occurs check: cannot construct the infinite type: b = a -> b
P...In the following code, a function has been applied to zero arguments, which the type checker suggests is too many.
```
Prelude> foldr (>>=) [] []
<interactive>:1:6:
Occurs check: cannot construct the infinite type: b = a -> b
Probable cause: `>>=' is applied to too many arguments
In the first argument of `foldr', namely `(>>=)'
In the expression: foldr (>>=) [] []
```
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | ----------------------- |
| Version | 6.8.2 |
| Type | Bug |
| TypeOfFailure | OtherFailure |
| Priority | normal |
| Resolution | Unresolved |
| Component | Compiler (Type checker) |
| Test case | |
| Differential revisions | |
| BlockedBy | |
| Related | |
| Blocking | |
| CC | |
| Operating system | Unknown |
| Architecture | Unknown |
</details>
<!-- {"blocked_by":[],"summary":"Odd probable cause given by type checker","status":"New","operating_system":"Unknown","component":"Compiler (Type checker)","related":[],"milestone":"","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"6.8.2","keywords":[],"differentials":[],"test_case":"","architecture":"Unknown","cc":[""],"type":"Bug","description":"In the following code, a function has been applied to zero arguments, which the type checker suggests is too many.\r\n\r\n{{{\r\nPrelude> foldr (>>=) [] []\r\n\r\n<interactive>:1:6:\r\n Occurs check: cannot construct the infinite type: b = a -> b\r\n Probable cause: `>>=' is applied to too many arguments\r\n In the first argument of `foldr', namely `(>>=)'\r\n In the expression: foldr (>>=) [] []\r\n}}}","type_of_failure":"OtherFailure","blocking":[]} -->7.6.1Simon Peyton JonesSimon Peyton Jones