GHC issueshttps://gitlab.haskell.org/ghc/ghc/-/issues2020-05-24T02:05:34Zhttps://gitlab.haskell.org/ghc/ghc/-/issues/18219Relax inferred context simplification to allow "exotic" contexts for Generali...2020-05-24T02:05:34ZAndrew PritchardRelax inferred context simplification to allow "exotic" contexts for GeneralizedNewtypeDeriving and DerivingVia instances.## Motivation
Many `GND` / `DerivingVia` instances that seem totally sensible must in practice be turned into `StandaloneDeriving` because their contexts cannot be inferred. However, `inferConstraintsCoerceBased` is already producing a...## Motivation
Many `GND` / `DerivingVia` instances that seem totally sensible must in practice be turned into `StandaloneDeriving` because their contexts cannot be inferred. However, `inferConstraintsCoerceBased` is already producing a sensible context for them, and all that's failing is simplifying that context. I suspect it's possible to simplify them differently from contexts coming from other deriving mechanisms, and make these deriving clauses work.
## Proposal
The following module defines a class and attempts to GND an instance of it, but fails because the inferred constraint simplifies to `C [a]`, which doesn't match any instance head.
```
{-# LANGUAGE DerivingStrategies #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
module Example (Thing) where
class C a where method :: a -> String
instance C [Bool] where method _ = ""
newtype Thing a = Thing [a] deriving newtype C
```
This happens because of the restriction described in the Note `[Exotic derived instance contexts]`. However, many uses of `DerivingVia` intuitively want to "just copy the context of the via instance". I'm having a hard time formalizing this intuition, since there can be odd situations like mutually recursive derived instances involving newtypes [1] or self-recursive newtypes [2]. But a first pass is that if the `via` type is imported from another module and does not use the newtype itself as a type parameter, the system of equations being simplified for the GND instance can't be recursive, and it should suffice to simplify the context in isolation.
I tried horribly hacking up a GHC build to skip all simplification for GND and DerivingVia instances just to make sure it's only the simplification that's breaking the instance, and it sort-of worked, in that it inferred a context that had unsimplified Coercible constraints but was otherwise reasonable:
```
b87b0c2c2947e1ccc983269180bfe604
$fCThing ::
(C [a],
([a] -> GHC.Base.String) ~R# (Thing a -> GHC.Base.String)) =>
C (Thing a)
DFunId
[]
```
These unsimplified Coercible constraints are a problem, though, since they break calling modules that don't import the relevant newtype constructors (and the stage2 GHC doesn't build). Of course this isn't meant to be a real implementation, just a way to prove to myself that `inferContextCoerceBased` was sufficient for these instances.
In general many of the new instances this enables would probably require `UndecidableInstances`, but I'm willing to enable that as necessary. Some more example modules affected by this:
A type family interfering with simplification:
```
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE DerivingStrategies #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE StandaloneDeriving #-}
{-# LANGUAGE TypeApplications #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE UndecidableInstances #-}
module Test where
import Data.Proxy (Proxy(..))
import GHC.TypeNats (Nat, KnownNat, natVal)
data SwarmOfNats = SwarmOfNats Nat Nat Nat
type family FstSwarm (x :: SwarmOfNats) :: Nat where
FstSwarm ('SwarmOfNats x y z) = x
class C a where method :: a -> String
instance KnownNat n => C (Proxy n) where method _ = show (natVal @n Proxy)
-- Fails simplifying because the context contains a type family application.
newtype Thing swarm = Thing (Proxy (FstSwarm swarm)) deriving newtype C
-- deriving newtype instance KnownNat (FstSwarm swarm) => C (Thing swarm)
```
A `FlexibleContexts` constraint on a MPTC interfering with simplification:
```
{-# LANGUAGE DeriveFoldable #-}
{-# LANGUAGE DerivingVia #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE StandaloneDeriving #-}
{-# LANGUAGE UndecidableInstances #-}
module Test where
-- Disregard that this technique is blatantly overkill here...
data Rope str = Leaf str | Append (Rope str) (Rope str) deriving Foldable
class C str a where method :: a -> Rope str
newtype WrappedC a = WrappedC { unWrappedC :: a }
instance C String a => Show (WrappedC a) where
showsPrec _p x s = foldr (++) s (method (unWrappedC x))
instance C [Char] a => C [Char] (Thing a) where
method Thing1 = Leaf "Thing1"
method (Thing2 x) = Append (Leaf "Thing2 ") (method x)
-- Fails because the inferred context simplifies to `C [Char] a`.
data Thing a = Thing1 | Thing2 a deriving Show via WrappedC (Thing a)
-- deriving via WrappedC (Thing a) instance C [Char] a => Show (Thing a)
```
[1]: A GND instance that would give a recursive system:
```
{-# LANGUAGE DerivingStrategies #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
module Test where
data Thing1 = Thing1 Thing2 Thing2 deriving Eq
newtype Thing2 = Thing2 Thing1 deriving newtype Eq
-- Eq Thing1 = Eq Thing2 u Eq Thing2
-- Eq Thing2 = Eq Thing1 u Coercible Thing2 Thing1
```
[2] A GND instance that would expand infinitely (but works because of the least-fixed-point simplification):
```
{-# LANGUAGE DerivingStrategies #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
{-# LANGUAGE ScopedTypeVariables #-}
module Test where
data Proxy a = Proxy
class ShowType a where showType :: Proxy a -> String
data Thing1 a
instance ShowType a => ShowType (Thing1 a) where
showType _ = "Thing1 " ++ showType (Proxy :: Proxy a)
newtype Weird a = Weird (Thing1 (Weird [a])) deriving newtype ShowType
-- ShowType (Weird a) = ShowType (Thing1 (Weird [a]))
-- = ShowType (Weird [a])
-- = ShowType (Thing1 (Weird [[a]]))
-- = ShowType (Weird [[a]])
-- ...
```https://gitlab.haskell.org/ghc/ghc/-/issues/18213GND generates code that instantiates coerce too much2020-10-31T21:03:41ZRyan ScottGND generates code that instantiates coerce too muchConsider this code from https://gitlab.haskell.org/ghc/ghc/issues/18148#note_270603:
```hs
{-# LANGUAGE AllowAmbiguousTypes #-}
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE DerivingStrategies #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUA...Consider this code from https://gitlab.haskell.org/ghc/ghc/issues/18148#note_270603:
```hs
{-# LANGUAGE AllowAmbiguousTypes #-}
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE DerivingStrategies #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
{-# LANGUAGE PolyKinds #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE StandaloneDeriving #-}
module Bug where
class Foo a where
bar :: forall (x :: a). ()
bar = ()
instance Foo Int
newtype Quux a = Quux a
-- deriving newtype instance _ => Foo (Quux Int)
deriving newtype instance Foo (Quux Int)
```
This typechecks in GHC 8.10.1. However, if you comment out the original `deriving newtype instance Foo (Quux Int)` line and uncomment the very similar line above it, it no longer typechecks:
```
Bug.hs:19:1: error:
• Couldn't match type ‘Int’ with ‘Quux Int’
arising from the coercion of the method ‘bar’
from type ‘forall (x :: Int). ()’
to type ‘forall (x :: Quux Int). ()’
• When deriving the instance for (Foo (Quux Int))
|
19 | deriving newtype instance _ => Foo (Quux Int)
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
```
This is a strange inconsistency, given how similar these standalone `deriving` declarations are. Why does the original succeed but the line above it fail?
As it turns out, both of these really ought to fail, but the original only succeeds due to an unfortunate fluke in the way `GeneralizedNewtypeDeriving` works. Here is the code that the original declaration generates (with `-ddump-deriv`):
```
==================== Derived instances ====================
Derived class instances:
instance Bug.Foo (Bug.Quux GHC.Types.Int) where
Bug.bar
= GHC.Prim.coerce @() @() (Bug.bar @GHC.Types.Int) ::
forall (x_aKF :: Bug.Quux GHC.Types.Int). ()
```
Notice that we are instantiating `coerce` with `@() @()`. But this is blatantly wrong—it really ought to be `coerce @(forall (x :: Int). ()) @(forall (x :: Quux Int). ())`, which the typechecker would reject (as it should). But GND generates `coerce @() @()` instead, and as a result, the use of `bar` on the RHS gets instantiated with `@Any`, which is not what was intended at all.
In contrast, the `deriving newtype instance _ => Foo (Quux Int)` line infers a `Coercible (forall (x :: Int). ()) (forall (x :: Quux Int). ())` constraint, which the constraint solver rejects (as it should). The original line does not use the same constraint-inference machinery, so it bypasses this step.
What can be done about this? It's tempting to have the original declaration generate this code instead:
```hs
instance Foo (Quux Int) where
bar = coerce @(forall (x :: Int). ())
@(forall (x :: Quux Int). ())
bar
```
Sadly, doing so would break a number of test cases that involve quantified constraints in instance contexts, such as `T15290`. See [`Note [GND and QuantifiedConstraints]`](https://gitlab.haskell.org/ghc/ghc/-/blob/9afd92512b41cf6c6de3a17b474d8d4bb01158c3/compiler/GHC/Tc/Deriv/Generate.hs#L1686-1773) for the full story. In order to make these test cases succeed (as a part of the fix for #15290), we employed an [ugly hack](132273f34e394bf7e900d0c15e01e91edd711890) where we split the `forall`s off of any types used to instantiate `coerce` in GND-generated code. But, as the example above demonstrates, this hack creates just as many problems as it solves.
@simonpj believes that this hack (and all of `Note [GND and QuantifiedConstraints]`) could be avoided. I don't quite understand his grand vision, so I'll let him comment here about what his vision entails.
Another similar example of this bug arising can be found in #18148. However, that issue is ensnared in a separate discussion about the roles of arguments to type classes, as the examples in #18148 crucially involve `ConstrainedClassMethods`. The underlying bug in this issue, on the other hand, does not fundamentally involve `ConstrainedClassMethods` in any way, so @simonpj and I have decided to track it separately here.https://gitlab.haskell.org/ghc/ghc/-/issues/18148ConstrainedClassMethods can trigger un-actionable redundant constraint warnin...2020-05-22T23:35:24ZKoz RossConstrainedClassMethods can trigger un-actionable redundant constraint warnings together with GND## Summary
If you use ``GeneralizedNewtypeDeriving`` (or indeed, ``DerivingVia``) to derive an instance of a type class whose methods have constraints that aren't in the type class head, it is possible to trigger redundant constraint wa...## Summary
If you use ``GeneralizedNewtypeDeriving`` (or indeed, ``DerivingVia``) to derive an instance of a type class whose methods have constraints that aren't in the type class head, it is possible to trigger redundant constraint warnings if the generated code would cause the constraints to be satisfied by whatever the type variables are set to. See the example given in 'steps to reproduce' for a demonstration. These warnings can't be actioned - the only option currently is to disable redundant constraint warnings completely.
## Steps to reproduce
Attempt to compile the following code with ``-Wredundant-constraints`` enabled:
```haskell
{-# LANGUAGE ConstrainedClassMethods #-}
{-# LANGUAGE DerivingStrategies #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
{-# LANGUAGE StandaloneDeriving #-}
module Baz where
class Foo a where
bar :: (Num a) => a -> a
bar = (+ 1)
instance Foo Int
newtype Quux a = Quux a
deriving newtype instance Foo (Quux Int)
```
This will emit a redundant constraint warning, as ``Int`` is already an instance of ``Num``.
## Expected behavior
Should compile, emitting no warnings.
## Environment
* GHC version used: 8.10.1
Optional:
* Operating System: GNU/Linux
* System Architecture: x86_64https://gitlab.haskell.org/ghc/ghc/-/issues/17518Can't derive TYPE rep instances2022-09-19T16:19:11ZIcelandjackCan't derive TYPE rep instances## Summary
Deriving fails when we have `TYPE rep`, not `Type`
```haskell
{-# Language DerivingStrategies #-}
{-# Language GeneralizedNewtypeDeriving #-}
{-# Language KindSignatures #-}
{-# Language MagicHash ...## Summary
Deriving fails when we have `TYPE rep`, not `Type`
```haskell
{-# Language DerivingStrategies #-}
{-# Language GeneralizedNewtypeDeriving #-}
{-# Language KindSignatures #-}
{-# Language MagicHash #-}
{-# Language PolyKinds #-}
{-# Language UnliftedNewtypes #-}
import GHC.Exts (TYPE, RuntimeRep(IntRep), Int#, (+#))
import Data.Coerce
class Num# (a# :: TYPE rep) where
add# :: a# -> a# -> a#
instance Num# Int# where
add# = (+#)
-- • Cannot derive well-kinded instance of form ‘Num# (IdInt# ...)’
-- Class ‘Num#’ expects an argument of kind ‘*’
-- • In the newtype declaration for ‘IdInt#’
newtype IdInt# = IdInt# Int#
deriving
newtype Num#
```
deriving works for a levity-polymorphic `Id#`
```haskell
newtype Id# (a# :: TYPE rep) = Id# a#
deriving
newtype Num#
```
but sadly only for `@LiftedRep`
```
> :set -fprint-explicit-kinds
> :i Num#
..
instance Num# @'LiftedRep a# =>
Num# @'LiftedRep (Id# @'LiftedRep a#)
```
## Proposed improvements or changes
The first one should be derived at `TYPE IntRep`
```haskell
instance Num# (IdInt# :: TYPE IntRep) where
add# :: IdInt# -> IdInt# -> IdInt#
add# = coerce (add# @IntRep @Int#)
```
but the second one wouldn't work for all `rep`, how can we get it to work
```haskell
-- Cannot use function with levity-polymorphic arguments:
-- coerce :: (a# -> a# -> a#) -> Id# a# -> Id# a# -> Id# a#
-- Levity-polymorphic arguments:
-- Id# a# :: TYPE rep
-- Id# a# :: TYPE rep^[[0m^[[0m
instance Num# a# => Num# (Id# a# :: TYPE rep) where
add# :: Id# a# -> Id# a# -> Id# a#
add# = coerce (add# @rep @a#)
```
## Environment
* GHC version used: 8.10.0.20191123
https://gitlab.haskell.org/ghc/ghc/-/issues/17241Replace useages of con2tag_* in the deriving code with data2tag#2021-02-09T20:13:52ZAndreas KlebingerReplace useages of con2tag_* in the deriving code with data2tag### Motivation
As I understand it we generate(ed?) con2tag_Con bindings in the deriving code well before data2Tag was a thing.
## Proposal
Now that we have data2Tag we should replace useages of con2tag with it.## Motivation
As I understand it we generate(ed?) con2tag_Con bindings in the deriving code well before data2Tag was a thing.
## Proposal
Now that we have data2Tag we should replace useages of con2tag with it.8.10.2https://gitlab.haskell.org/ghc/ghc/-/issues/17183-XDerivingVia (and deriving strategies) is under specified in the manual2023-06-09T10:09:43ZRichard Eisenbergrae@richarde.dev-XDerivingVia (and deriving strategies) is under specified in the manualI had forgotten the syntax for deriving-strategies. Specifically, I wanted to know whether I had to put the strategy *before* or *after* the list of classes. So I looked it up.... but the [manual](https://downloads.haskell.org/~ghc/lates...I had forgotten the syntax for deriving-strategies. Specifically, I wanted to know whether I had to put the strategy *before* or *after* the list of classes. So I looked it up.... but the [manual](https://downloads.haskell.org/~ghc/latest/docs/html/users_guide/glasgow_exts.html#deriving-strategies) doesn't say. The examples suggest that the strategy comes before, but then in the `-XDerivingVia` section, the strategy comes after. Are both allowed? Is `via` allowed prefix? It is a mystery.
And then I looked through the `-XDerivingVia` [documentation](https://downloads.haskell.org/~ghc/latest/docs/html/users_guide/glasgow_exts.html#deriving-via). That is explained entirely by example, with no standalone specification. Yet the specification really has been worked out -- it's in the paper. This text should be incorporated into the users' guide, along with a link to the paper (which I also did not see). Also needed are a description of how typing works -- or at least scoping. It's very non-trivial.https://gitlab.haskell.org/ghc/ghc/-/issues/17037Stock deriving improvements2023-06-16T04:12:21ZSophie TaylorStock deriving improvements## Motivation
Trying to use GHC-derived code in performance-sensitive applications leads to several problems:
1. SPECIALISE pragmas have nothing to inline if the relevant types with GHC-derived instances are defined in another file
2. ...## Motivation
Trying to use GHC-derived code in performance-sensitive applications leads to several problems:
1. SPECIALISE pragmas have nothing to inline if the relevant types with GHC-derived instances are defined in another file
2. No class law RULES seem to be generated, either. This is particularly troublesome with DeriveFunctor/DeriveFoldable/DeriveTraversable.
## Proposal
1. GHC-derived instances should have INLINABLE pragmas.
2. I'm pretty certain that GHC generates law-abiding instances for Functor/Foldable/Traversable, so the relevant laws should be generated as RULES specific for the types its generating instances for.https://gitlab.haskell.org/ghc/ghc/-/issues/17013GHC accepts derived instances that violate functional dependencies2021-10-30T13:54:47ZAlexis KingGHC accepts derived instances that violate functional dependencies## Summary
Instances generated using `DerivingVia` are accepted even though equivalent handwritten instances are rejected due to violation of the (liberal) coverage condition.
## Steps to reproduce
This module demonstrates the problem...## Summary
Instances generated using `DerivingVia` are accepted even though equivalent handwritten instances are rejected due to violation of the (liberal) coverage condition.
## Steps to reproduce
This module demonstrates the problem:
```haskell
{-# LANGUAGE DerivingVia #-}
{-# LANGUAGE FunctionalDependencies #-}
{-# LANGUAGE FlexibleInstances #-}
module DerivingViaBug where
class C a b | b -> a
newtype A t a = A a
instance C t (A t a)
data T = T
deriving (C a) via (A () T)
```
The above program is accepted. But if we write the `C a T` instance manually, rather than deriving it, the program is rejected:
```haskell
data T = T
instance C a T
```
```
src/DerivingViaBug.hs:13:10: error:
• Illegal instance declaration for ‘C a T’
The coverage condition fails in class ‘C’
for functional dependency: ‘b -> a’
Reason: lhs type ‘T’ does not determine rhs type ‘a’
Un-determined variable: a
• In the instance declaration for ‘C a T’
|
13 | instance C a T
| ^^^^^
```
## Expected behavior
The simplest solution to this problem would be to reject the derived instance. However, this introduces a bit of an inconsistency between functional dependencies and associated types. Consider the following similar program, which uses associated types instead of functional dependencies:
```haskell
{-# LANGUAGE DerivingVia #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE UndecidableInstances #-}
module DerivingViaBug where
class C a where
type F a
newtype A t a = A a
instance C (A t a) where
type F (A t a) = t
data T = T
deriving (C) via (A () T)
```
This program is accepted, and the behavior is reasonable. The derived instance is
```haskell
instance C T where
type F T = F (A () T)
```
so `F T` is ultimately `()`. To achieve analogous behavior for functional dependencies, it seems like a reasonable derived instance could be
```haskell
instance C () T
```
which can be constructed by applying the substitution {`t` ↦ `()`, `a` ↦ `T`} to the original `C t (A t a)` instance declaration. I haven’t thought about it enough to say whether or not that would cause more problems than it would solve, however.
## Environment
* GHC version used: 8.6.5
* Operating System: macOS 10.14.5 (18F132)
* System Architecture: x86_64https://gitlab.haskell.org/ghc/ghc/-/issues/15969Generic1 deriving should use more coercions2022-06-19T21:04:37ZDavid FeuerGeneric1 deriving should use more coercionsConsider
```hs
newtype Foo a = Foo (Maybe [a]) deriving (Generic1)
```
This produces some rather unsatisfactory Core:
```
-- to1 worker
Travv.$fGeneric1Foo1 :: forall a. Rep1 Foo a -> Maybe [a]
Travv.$fGeneric1Foo1
= \ (@ a_a7RL) (d...Consider
```hs
newtype Foo a = Foo (Maybe [a]) deriving (Generic1)
```
This produces some rather unsatisfactory Core:
```
-- to1 worker
Travv.$fGeneric1Foo1 :: forall a. Rep1 Foo a -> Maybe [a]
Travv.$fGeneric1Foo1
= \ (@ a_a7RL) (ds_d9dZ :: Rep1 Foo a_a7RL) ->
case ds_d9dZ `cast` <Co:103> of {
Nothing -> GHC.Maybe.Nothing @ [a_a7RL];
Just a1_a9fD -> GHC.Maybe.Just @ [a_a7RL] (a1_a9fD `cast` <Co:5>)
}
-- from1 worker
Travv.$fGeneric1Foo2 :: forall a. Foo a -> Maybe (Rec1 [] a)
Travv.$fGeneric1Foo2
= \ (@ a_a7R6) (x_a7GJ :: Foo a_a7R6) ->
case x_a7GJ `cast` <Co:2> of {
Nothing -> GHC.Maybe.Nothing @ (Rec1 [] a_a7R6);
Just a1_a9fD ->
GHC.Maybe.Just @ (Rec1 [] a_a7R6) (a1_a9fD `cast` <Co:6>)
}
```
Both of these functions could be implemented as safe coercions, but neither of them is! Similarly, if I define
```hs
data Bar a = Bar (Maybe [a]) deriving Generic1
```
I get a `to1` worker that looks like
```
Travv.$fGeneric1Bar_$cto1 :: forall a. Rep1 Bar a -> Bar a
Travv.$fGeneric1Bar_$cto1
= \ (@ a_a7UA) (ds_d9ho :: Rep1 Bar a_a7UA) ->
Travv.Bar
@ a_a7UA
(case ds_d9ho `cast` <Co:103> of {
Nothing -> GHC.Maybe.Nothing @ [a_a7UA];
Just a1_a9iK -> GHC.Maybe.Just @ [a_a7UA] (a1_a9iK `cast` <Co:5>)
})
```
That `case` expression should really just be a cast.
I think the basic trick is probably to inspect the role of the type argument of each type in a composition, using that to work out whether to coerce that step.
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | ------------ |
| Version | 8.6.2 |
| Type | Bug |
| TypeOfFailure | OtherFailure |
| Priority | normal |
| Resolution | Unresolved |
| Component | Compiler |
| Test case | |
| Differential revisions | |
| BlockedBy | |
| Related | |
| Blocking | |
| CC | RyanGlScott |
| Operating system | |
| Architecture | |
</details>
<!-- {"blocked_by":[],"summary":"Generic1 deriving should use more coercions","status":"New","operating_system":"","component":"Compiler","related":[],"milestone":"8.8.1","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"8.6.2","keywords":["Generics"],"differentials":[],"test_case":"","architecture":"","cc":["RyanGlScott"],"type":"Bug","description":"Consider\r\n\r\n{{{#!hs\r\nnewtype Foo a = Foo (Maybe [a]) deriving (Generic1)\r\n}}}\r\n\r\nThis produces some rather unsatisfactory Core:\r\n\r\n{{{\r\n-- to1 worker\r\nTravv.$fGeneric1Foo1 :: forall a. Rep1 Foo a -> Maybe [a]\r\nTravv.$fGeneric1Foo1\r\n = \\ (@ a_a7RL) (ds_d9dZ :: Rep1 Foo a_a7RL) ->\r\n case ds_d9dZ `cast` <Co:103> of {\r\n Nothing -> GHC.Maybe.Nothing @ [a_a7RL];\r\n Just a1_a9fD -> GHC.Maybe.Just @ [a_a7RL] (a1_a9fD `cast` <Co:5>)\r\n}\r\n\r\n-- from1 worker\r\nTravv.$fGeneric1Foo2 :: forall a. Foo a -> Maybe (Rec1 [] a)\r\nTravv.$fGeneric1Foo2\r\n = \\ (@ a_a7R6) (x_a7GJ :: Foo a_a7R6) ->\r\n case x_a7GJ `cast` <Co:2> of {\r\n Nothing -> GHC.Maybe.Nothing @ (Rec1 [] a_a7R6);\r\n Just a1_a9fD ->\r\n GHC.Maybe.Just @ (Rec1 [] a_a7R6) (a1_a9fD `cast` <Co:6>)\r\n }\r\n}}}\r\n\r\nBoth of these functions could be implemented as safe coercions, but neither of them is! Similarly, if I define\r\n\r\n{{{#!hs\r\ndata Bar a = Bar (Maybe [a]) deriving Generic1\r\n}}}\r\n\r\nI get a `to1` worker that looks like\r\n\r\n{{{\r\nTravv.$fGeneric1Bar_$cto1 :: forall a. Rep1 Bar a -> Bar a\r\nTravv.$fGeneric1Bar_$cto1\r\n = \\ (@ a_a7UA) (ds_d9ho :: Rep1 Bar a_a7UA) ->\r\n Travv.Bar\r\n @ a_a7UA\r\n (case ds_d9ho `cast` <Co:103> of {\r\n Nothing -> GHC.Maybe.Nothing @ [a_a7UA];\r\n Just a1_a9iK -> GHC.Maybe.Just @ [a_a7UA] (a1_a9iK `cast` <Co:5>)\r\n })\r\n}}}\r\n\r\nThat `case` expression should really just be a cast.\r\n\r\nI think the basic trick is probably to inspect the role of the type argument of each type in a composition, using that to work out whether to coerce that step.","type_of_failure":"OtherFailure","blocking":[]} -->https://gitlab.haskell.org/ghc/ghc/-/issues/15868Standard deriving should be less conservative when `UndecidableInstances` is ...2019-07-22T17:04:42Zedsko@edsko.netStandard deriving should be less conservative when `UndecidableInstances` is enabledThe following program
```hs
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE StandaloneDeriving #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE UndecidableInstances #-}
module Exp where
...The following program
```hs
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE StandaloneDeriving #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE UndecidableInstances #-}
module Exp where
type family F a
data T a = MkT (F a)
deriving instance Eq (F a) => Eq (T a)
data T2 a = T2 (T a)
deriving (Eq)
```
results in a type error
```
• No instance for (Eq (F a))
arising from the first field of ‘T2’ (type ‘T a’)
```
According the manual this is expected behaviour (https://downloads.haskell.org/\~ghc/latest/docs/html/users_guide/glasgow_exts.html\#inferred-context-for-deriving-clauses), but it is unfortunate; it seems to me that there is no deep reason that this instance should be rejected, other than an overly conservative check in the deriving machinery; I propose that this check is relaxed when the `UndecidableInstances` extension is enabled. Mind that I'm *not* proposing that it should also be able to infer the right constraints for `T` itself; but once I write such an explicit context myself once (for `T`), it seems to me that deriving the *same* constraints also for `T2` should be easy.
Note that right now we can work-around this problem using
```hs
class Eq (F a) => EqF a
deriving instance EqF a => Eq (T a)
data T2 a = T2 (T a)
deriving (Eq)
```
Normally however for such a class synonym we would then provide a single "authoritative" instance:
```hs
class Eq (F a) => EqF a
instance Eq (F a) => EqF a
```
but if we do that then we are back at the same error for `T2`, because ghc will go from the `EqF a` constraint to the `Eq (F a)` constraint, and then refuse to add that constraint.
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | -------------- |
| Version | 8.6.1 |
| Type | FeatureRequest |
| TypeOfFailure | OtherFailure |
| Priority | normal |
| Resolution | Unresolved |
| Component | Compiler |
| Test case | |
| Differential revisions | |
| BlockedBy | |
| Related | |
| Blocking | |
| CC | |
| Operating system | |
| Architecture | |
</details>
<!-- {"blocked_by":[],"summary":"Standard deriving should be less conservative when `UndecidableInstances` is enabled","status":"New","operating_system":"","component":"Compiler","related":[],"milestone":"","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"8.6.1","keywords":[],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"FeatureRequest","description":"The following program\r\n\r\n{{{#!hs\r\n{-# LANGUAGE FlexibleContexts #-}\r\n{-# LANGUAGE FlexibleInstances #-}\r\n{-# LANGUAGE StandaloneDeriving #-}\r\n{-# LANGUAGE TypeFamilies #-}\r\n{-# LANGUAGE UndecidableInstances #-}\r\n\r\nmodule Exp where\r\n\r\ntype family F a\r\n\r\ndata T a = MkT (F a)\r\n\r\nderiving instance Eq (F a) => Eq (T a)\r\n\r\ndata T2 a = T2 (T a)\r\n deriving (Eq)\r\n}}}\r\n\r\nresults in a type error\r\n\r\n{{{\r\n • No instance for (Eq (F a))\r\n arising from the first field of ‘T2’ (type ‘T a’)\r\n}}}\r\n\r\nAccording the manual this is expected behaviour (https://downloads.haskell.org/~ghc/latest/docs/html/users_guide/glasgow_exts.html#inferred-context-for-deriving-clauses), but it is unfortunate; it seems to me that there is no deep reason that this instance should be rejected, other than an overly conservative check in the deriving machinery; I propose that this check is relaxed when the `UndecidableInstances` extension is enabled. Mind that I'm ''not'' proposing that it should also be able to infer the right constraints for `T` itself; but once I write such an explicit context myself once (for `T`), it seems to me that deriving the ''same'' constraints also for `T2` should be easy.\r\n\r\nNote that right now we can work-around this problem using\r\n\r\n{{{#!hs\r\nclass Eq (F a) => EqF a\r\n\r\nderiving instance EqF a => Eq (T a)\r\n\r\ndata T2 a = T2 (T a)\r\n deriving (Eq)\r\n}}}\r\n\r\nNormally however for such a class synonym we would then provide a single \"authoritative\" instance:\r\n\r\n{{{#!hs\r\nclass Eq (F a) => EqF a\r\ninstance Eq (F a) => EqF a\r\n}}}\r\n\r\nbut if we do that then we are back at the same error for `T2`, because ghc will go from the `EqF a` constraint to the `Eq (F a)` constraint, and then refuse to add that constraint. ","type_of_failure":"OtherFailure","blocking":[]} -->https://gitlab.haskell.org/ghc/ghc/-/issues/15650Add (or document if already exist) ability to derive custom typeclasses via s...2023-06-09T09:15:40ZDmitrii KovanikovAdd (or document if already exist) ability to derive custom typeclasses via source plugins## Problem
Suppose, I have some custom typeclass `Foo` defined in some library `foo`:
```hs
class Foo a where
... some methods ...
```
I would like to be able to derive instances of this typeclass for any possible data type using ...## Problem
Suppose, I have some custom typeclass `Foo` defined in some library `foo`:
```hs
class Foo a where
... some methods ...
```
I would like to be able to derive instances of this typeclass for any possible data type using `deriving` clause just like GHC already does for typeclasses `Eq`, `Ord`, `Show`, `Read`, `Enum`, etc.:
```hs
data Bar = Bar | Baz
deriving (Eq, Ord, Foo)
```
There're already two possible ways to derive instances of custom typeclasses:
1. `anyclass` deriving strategy (usually involves `Generic`)
1. `-XTemplateHaskell` solution.
But I would like to have source-plugin-based solution for this problem so I can just add `-fplugin=Foo.Plugin` and enjoy deriving capabilities.
## Advantage over existing approaches
Solution with `-XTemplateHaskell` is not that pleasant to write and easy to maintain (you need to use libraries like http://hackage.haskell.org/package/th-abstraction to support multiple GHC versions),involves scoping restriction and is syntactically uglier. Compare:
```hs
{-# LANGUAGE TemplateHaskell #-}
data Bar = Bar | Baz
deriving (Eq, Ord)
deriveFoo ''Bar
```
Solution with something like `Generic` introduces performance overhead (required for to/from generic representation conversion). This might not be significant for something like *parsing CLI arguments* but it's more important if you want to have efficient binary serialisation.
Also, it's known that deriving typeclasses is a relatively slow compilation process (https://github.com/tfausak/tfausak.github.io/issues/127) so there's slight chance that deriving typeclass manually can be slightly faster than deriving `Generic + MyClass`. Especially when maintainers of plugins can experiment with some caching strategies for deriving typeclasses.
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | -------------- |
| Version | 8.6.1-beta1 |
| Type | FeatureRequest |
| TypeOfFailure | OtherFailure |
| Priority | normal |
| Resolution | Unresolved |
| Component | Compiler |
| Test case | |
| Differential revisions | |
| BlockedBy | |
| Related | |
| Blocking | |
| CC | |
| Operating system | |
| Architecture | |
</details>
<!-- {"blocked_by":[],"summary":"Add (or document if already exist) ability to derive custom typeclasses via source plugins","status":"New","operating_system":"","component":"Compiler","related":[],"milestone":"8.6.1","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"8.6.1-beta1","keywords":["plugins,deriving,typeclass","source"],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"FeatureRequest","description":"== Problem\r\n\r\nSuppose, I have some custom typeclass `Foo` defined in some library `foo`:\r\n\r\n{{{#!hs\r\nclass Foo a where\r\n ... some methods ...\r\n}}}\r\n\r\nI would like to be able to derive instances of this typeclass for any possible data type using `deriving` clause just like GHC already does for typeclasses `Eq`, `Ord`, `Show`, `Read`, `Enum`, etc.:\r\n\r\n{{{#!hs\r\ndata Bar = Bar | Baz\r\n deriving (Eq, Ord, Foo)\r\n}}}\r\n\r\nThere're already two possible ways to derive instances of custom typeclasses:\r\n\r\n1. `anyclass` deriving strategy (usually involves `Generic`)\r\n2. `-XTemplateHaskell` solution.\r\n\r\nBut I would like to have source-plugin-based solution for this problem so I can just add `-fplugin=Foo.Plugin` and enjoy deriving capabilities.\r\n\r\n== Advantage over existing approaches\r\n\r\nSolution with `-XTemplateHaskell` is not that pleasant to write and easy to maintain (you need to use libraries like http://hackage.haskell.org/package/th-abstraction to support multiple GHC versions),involves scoping restriction and is syntactically uglier. Compare:\r\n\r\n{{{#!hs\r\n{-# LANGUAGE TemplateHaskell #-}\r\n\r\ndata Bar = Bar | Baz\r\n deriving (Eq, Ord)\r\n\r\nderiveFoo ''Bar\r\n}}}\r\n\r\nSolution with something like `Generic` introduces performance overhead (required for to/from generic representation conversion). This might not be significant for something like ''parsing CLI arguments'' but it's more important if you want to have efficient binary serialisation. \r\n\r\nAlso, it's known that deriving typeclasses is a relatively slow compilation process (https://github.com/tfausak/tfausak.github.io/issues/127) so there's slight chance that deriving typeclass manually can be slightly faster than deriving `Generic + MyClass`. Especially when maintainers of plugins can experiment with some caching strategies for deriving typeclasses.","type_of_failure":"OtherFailure","blocking":[]} -->8.6.1https://gitlab.haskell.org/ghc/ghc/-/issues/15376GHC determine illegal kind for standalone deriving with Deriving via2023-03-02T20:36:13Zmizunashi_manaGHC determine illegal kind for standalone deriving with Deriving viaHappy to release GHC 8.6.1-alpha1! I used it to test new extensions, and then I met below errors:
```
$ ghci-8.6.0.20180627
GHCi, version 8.6.0.20180627: http://www.haskell.org/ghc/ :? for help
Prelude> :set -XDerivingVia -XStandaloneD...Happy to release GHC 8.6.1-alpha1! I used it to test new extensions, and then I met below errors:
```
$ ghci-8.6.0.20180627
GHCi, version 8.6.0.20180627: http://www.haskell.org/ghc/ :? for help
Prelude> :set -XDerivingVia -XStandaloneDeriving
Prelude> newtype FunctorWrapped f a = FunctorWrapped (f a)
Prelude> deriving via f instance Functor f => Functor (FunctorWrapped f)
<interactive>:3:33: error:
• Expected kind ‘* -> *’, but ‘f’ has kind ‘*’
• In the first argument of ‘Functor’, namely ‘f’
In the stand-alone deriving instance for
‘Functor f => Functor (FunctorWrapped f)’
<interactive>:3:62: error:
• Expected kind ‘* -> *’, but ‘f’ has kind ‘*’
• In the first argument of ‘FunctorWrapped’, namely ‘f’
In the first argument of ‘Functor’, namely ‘(FunctorWrapped f)’
In the stand-alone deriving instance for
‘Functor f => Functor (FunctorWrapped f)’
```
However,
```
newtype FunctorWrapped f a = FunctorWrapped (f a)
deriving Functor via f
```
is passed through on GHC 8.6.1-alpha1.
Is this a bug or my misunderstand?
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | ------------ |
| Version | |
| 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":"GHC determine illegal kind for standalone deriving with Deriving via","status":"New","operating_system":"","component":"Compiler","related":[],"milestone":"8.6.1","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"","keywords":[],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"Bug","description":"Happy to release GHC 8.6.1-alpha1! I used it to test new extensions, and then I met below errors:\r\n\r\n{{{\r\n$ ghci-8.6.0.20180627\r\nGHCi, version 8.6.0.20180627: http://www.haskell.org/ghc/ :? for help\r\nPrelude> :set -XDerivingVia -XStandaloneDeriving\r\nPrelude> newtype FunctorWrapped f a = FunctorWrapped (f a)\r\nPrelude> deriving via f instance Functor f => Functor (FunctorWrapped f)\r\n\r\n<interactive>:3:33: error:\r\n • Expected kind ‘* -> *’, but ‘f’ has kind ‘*’\r\n • In the first argument of ‘Functor’, namely ‘f’\r\n In the stand-alone deriving instance for\r\n ‘Functor f => Functor (FunctorWrapped f)’\r\n\r\n<interactive>:3:62: error:\r\n • Expected kind ‘* -> *’, but ‘f’ has kind ‘*’\r\n • In the first argument of ‘FunctorWrapped’, namely ‘f’\r\n In the first argument of ‘Functor’, namely ‘(FunctorWrapped f)’\r\n In the stand-alone deriving instance for\r\n ‘Functor f => Functor (FunctorWrapped f)’\r\n}}}\r\n\r\nHowever,\r\n\r\n{{{\r\nnewtype FunctorWrapped f a = FunctorWrapped (f a)\r\n deriving Functor via f\r\n}}}\r\n\r\nis passed through on GHC 8.6.1-alpha1.\r\n\r\nIs this a bug or my misunderstand?","type_of_failure":"OtherFailure","blocking":[]} -->https://gitlab.haskell.org/ghc/ghc/-/issues/15151Better Interaction Between Specialization and GND2019-07-07T18:14:02ZAndrew MartinBetter Interaction Between Specialization and GNDLet us consider the following code:
```
-- Sort.hs
sort :: (Prim a, Ord a) => MutablePrimArray s a -> ST s ()
sort mutArr = ...
{-# SPECIALIZE sort :: MutablePrimArray s Int -> ST s () -#}
{-# SPECIALIZE sort :: MutablePrimArray s Int8 ...Let us consider the following code:
```
-- Sort.hs
sort :: (Prim a, Ord a) => MutablePrimArray s a -> ST s ()
sort mutArr = ...
{-# SPECIALIZE sort :: MutablePrimArray s Int -> ST s () -#}
{-# SPECIALIZE sort :: MutablePrimArray s Int8 -> ST s () -#}
{-# SPECIALIZE sort :: MutablePrimArray s Word8 -> ST s () -#}
...
```
For reference, a `MutablePrimArray` is a `MutableByteArray` with a phantom type variable to tag the element type. This sorting algorithm may be implemented in any number of ways, and the implementation is unimportant here. The specialize pragmas are intended to capture a number of common use cases. Here's where a problem arises:
```
-- Example.hs
newtype PersonId = PersonId Int
deriving (Eq,Ord,Prim)
sortPeople :: MutablePrimArray s PersonId -> MutablePrimArray s PersonId
sortPeople x = sort x
```
There isn't a rewrite rule that specializes the `sort` function when we are dealing with `PersonId`. So, we end up with a slower version of the code that explicitly passes all the dictionaries. One solution would be to just use `INLINABLE` instead. Then we don't have to try to list every type, and we just let the specialization be generate at the call site. But this isn't totally satisfying. There are a lot of types that are just newtype wrappers around `Int`. Why should we have an extra copy of the same code for each of them? (Even without newtypes, `INLINABLE` can still result in duplication if neither of the modules that needs a specialization transitively imports the other).
What I'm suggesting is that rewrite rules (like those generated by `SPECIALIZE`) could target not just the given type but also any newtype around it, provided that all typeclass instances required by the function were the result of GND. The only situations where this is unsound are situations where the user was already doing something unsound with rewrite rules. There are several implementation difficulties:
- In core, there is no good way to tell that a typeclass instance dictionary was the result of GND. I'm not sure how to work around this.
- `Eq` and `Ord` usually aren't handled by the `newtype` deriving strategy. They are handled by the `stock` strategy, which produces code with equivalent behavior but is nevertheless different code.
- The rewrite rule would need to look at additional arguments beyond the type arguments.
I suspect that these difficulties would make such this feature difficult to implement, but this feature would help me with some of my libraries and applications.
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | -------------- |
| Version | 8.4.2 |
| Type | FeatureRequest |
| TypeOfFailure | OtherFailure |
| Priority | normal |
| Resolution | Unresolved |
| Component | Compiler |
| Test case | |
| Differential revisions | |
| BlockedBy | |
| Related | |
| Blocking | |
| CC | |
| Operating system | |
| Architecture | |
</details>
<!-- {"blocked_by":[],"summary":"Better Interaction Specialization and GND","status":"New","operating_system":"","component":"Compiler","related":[],"milestone":"8.6.1","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"8.4.2","keywords":[],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"FeatureRequest","description":"Let us consider the following code:\r\n\r\n{{{\r\n-- Sort.hs\r\nsort :: (Prim a, Ord a) => MutablePrimArray s a -> ST s ()\r\nsort mutArr = ...\r\n{-# SPECIALIZE sort :: MutablePrimArray s Int -> ST s () -#}\r\n{-# SPECIALIZE sort :: MutablePrimArray s Int8 -> ST s () -#}\r\n{-# SPECIALIZE sort :: MutablePrimArray s Word8 -> ST s () -#}\r\n...\r\n}}}\r\n\r\nFor reference, a `MutablePrimArray` is a `MutableByteArray` with a phantom type variable to tag the element type. This sorting algorithm may be implemented in any number of ways, and the implementation is unimportant here. The specialize pragmas are intended to capture a number of common use cases. Here's where a problem arises:\r\n\r\n{{{\r\n-- Example.hs\r\nnewtype PersonId = PersonId Int\r\n deriving (Eq,Ord,Prim)\r\nsortPeople :: MutablePrimArray s PersonId -> MutablePrimArray s PersonId\r\nsortPeople x = sort x\r\n}}}\r\n\r\nThere isn't a rewrite rule that specializes the `sort` function when we are dealing with `PersonId`. So, we end up with a slower version of the code that explicitly passes all the dictionaries. One solution would be to just use `INLINABLE` instead. Then we don't have to try to list every type, and we just let the specialization be generate at the call site. But this isn't totally satisfying. There are a lot of types that are just newtype wrappers around `Int`. Why should we have an extra copy of the same code for each of them? (Even without newtypes, `INLINABLE` can still result in duplication if neither of the modules that needs a specialization transitively imports the other).\r\n\r\nWhat I'm suggesting is that rewrite rules (like those generated by `SPECIALIZE`) could target not just the given type but also any newtype around it, provided that all typeclass instances required by the function were the result of GND. The only situations where this is unsound are situations where the user was already doing something unsound with rewrite rules. There are several implementation difficulties:\r\n\r\n* In core, there is no good way to tell that a typeclass instance dictionary was the result of GND. I'm not sure how to work around this.\r\n* `Eq` and `Ord` usually aren't handled by the `newtype` deriving strategy. They are handled by the `stock` strategy, which produces code with equivalent behavior but is nevertheless different code.\r\n* The rewrite rule would need to look at additional arguments beyond the type arguments.\r\n\r\nI suspect that these difficulties would make such this feature difficult to implement, but this feature would help me with some of my libraries and applications.","type_of_failure":"OtherFailure","blocking":[]} -->Research neededhttps://gitlab.haskell.org/ghc/ghc/-/issues/14331Overzealous free-floating kind check causes deriving clause to be rejected2023-02-01T20:13:20ZRyan ScottOverzealous free-floating kind check causes deriving clause to be rejectedGHC rejects this program:
```hs
{-# LANGUAGE DeriveAnyClass #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE PolyKinds #-}
module Bug where
class C a b
data D = D deriving (C (a :: k))
```
```
GHCi, version 8.2.1: http://www.h...GHC rejects this program:
```hs
{-# LANGUAGE DeriveAnyClass #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE PolyKinds #-}
module Bug where
class C a b
data D = D deriving (C (a :: k))
```
```
GHCi, version 8.2.1: http://www.haskell.org/ghc/ :? for help
Loaded GHCi configuration from /home/rgscott/.ghci
[1 of 1] Compiling Bug ( Bug.hs, interpreted )
Bug.hs:8:1: error:
Kind variable ‘k’ is implicitly bound in datatype
‘D’, but does not appear as the kind of any
of its type variables. Perhaps you meant
to bind it (with TypeInType) explicitly somewhere?
|
8 | data D = D deriving (C (a :: k))
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
```
But it really shouldn't, since it's quite possible to write the code that is should generate:
```hs
instance C (a :: k) D
```
Curiously, this does not appear to happen for data family instances, as this typechecks:
```hs
{-# LANGUAGE DeriveAnyClass #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE PolyKinds #-}
{-# LANGUAGE TypeFamilies #-}
module Bug where
class C a b
data family D1
data instance D1 = D1 deriving (C (a :: k))
class E where
data D2
instance E where
data D2 = D2 deriving (C (a :: k))
```
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | ----------------------- |
| Version | 8.2.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":"Overzealous free-floating kind check causes deriving clause to be rejected","status":"New","operating_system":"","component":"Compiler (Type checker)","related":[],"milestone":"","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"8.2.1","keywords":["deriving"],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"Bug","description":"GHC rejects this program:\r\n\r\n{{{#!hs\r\n{-# LANGUAGE DeriveAnyClass #-}\r\n{-# LANGUAGE MultiParamTypeClasses #-}\r\n{-# LANGUAGE PolyKinds #-}\r\nmodule Bug where\r\n\r\nclass C a b\r\n\r\ndata D = D deriving (C (a :: k))\r\n}}}\r\n\r\n{{{\r\nGHCi, version 8.2.1: http://www.haskell.org/ghc/ :? for help\r\nLoaded GHCi configuration from /home/rgscott/.ghci\r\n[1 of 1] Compiling Bug ( Bug.hs, interpreted )\r\n\r\nBug.hs:8:1: error:\r\n Kind variable ‘k’ is implicitly bound in datatype\r\n ‘D’, but does not appear as the kind of any\r\n of its type variables. Perhaps you meant\r\n to bind it (with TypeInType) explicitly somewhere?\r\n |\r\n8 | data D = D deriving (C (a :: k))\r\n | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\r\n}}}\r\n\r\nBut it really shouldn't, since it's quite possible to write the code that is should generate:\r\n\r\n{{{#!hs\r\ninstance C (a :: k) D\r\n}}}\r\n\r\nCuriously, this does not appear to happen for data family instances, as this typechecks:\r\n\r\n{{{#!hs\r\n{-# LANGUAGE DeriveAnyClass #-}\r\n{-# LANGUAGE MultiParamTypeClasses #-}\r\n{-# LANGUAGE PolyKinds #-}\r\n{-# LANGUAGE TypeFamilies #-}\r\nmodule Bug where\r\n\r\nclass C a b\r\n\r\ndata family D1\r\ndata instance D1 = D1 deriving (C (a :: k))\r\n\r\nclass E where\r\n data D2\r\n\r\ninstance E where\r\n data D2 = D2 deriving (C (a :: k))\r\n}}}","type_of_failure":"OtherFailure","blocking":[]} -->https://gitlab.haskell.org/ghc/ghc/-/issues/14030Implement the "Derive Lift instances for data types in template-haskell" prop...2024-03-18T14:36:50ZRyan ScottImplement the "Derive Lift instances for data types in template-haskell" proposalBack in September 2015, I [proposed](https://mail.haskell.org/pipermail/libraries/2015-September/026117.html) using the `DeriveLift` extension to, well, derive `Lift` instance for data types in the `template-haskell` library. The proposa...Back in September 2015, I [proposed](https://mail.haskell.org/pipermail/libraries/2015-September/026117.html) using the `DeriveLift` extension to, well, derive `Lift` instance for data types in the `template-haskell` library. The proposal was well received, but I was unable to implement it at the time due to `DeriveLift`'s newness (having only been introduced in GHC 8.0). Now that GHC 8.0 is the oldest version of GHC that we support bootstrapping with, this is no longer an obstacle.
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | ---------------- |
| Version | 8.3 |
| Type | Task |
| TypeOfFailure | OtherFailure |
| Priority | normal |
| Resolution | Unresolved |
| Component | Template Haskell |
| Test case | |
| Differential revisions | |
| BlockedBy | |
| Related | |
| Blocking | |
| CC | |
| Operating system | |
| Architecture | |
</details>
<!-- {"blocked_by":[],"summary":"Implement the \"Derive Lift instances for data types in template-haskell\" proposal","status":"New","operating_system":"","component":"Template Haskell","related":[],"milestone":"8.4.1","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"8.3","keywords":[],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"Task","description":"Back in September 2015, I [https://mail.haskell.org/pipermail/libraries/2015-September/026117.html proposed] using the `DeriveLift` extension to, well, derive `Lift` instance for data types in the `template-haskell` library. The proposal was well received, but I was unable to implement it at the time due to `DeriveLift`'s newness (having only been introduced in GHC 8.0). Now that GHC 8.0 is the oldest version of GHC that we support bootstrapping with, this is no longer an obstacle.","type_of_failure":"OtherFailure","blocking":[]} -->https://gitlab.haskell.org/ghc/ghc/-/issues/13957Allow deriving multiparameter type classes with representationally equal argu...2019-07-07T18:19:11ZIcelandjackAllow deriving multiparameter type classes with representationally equal argumentsThis currently works
```hs
{-# Language DerivingStrategies, MultiParamTypeClasses, FunctionalDependencies, GeneralizedNewtypeDeriving #-}
import Data.Kind
import Data.Functor.Identity
class SIEVE f p | p -> f where
sIEVE :: p a b ->...This currently works
```hs
{-# Language DerivingStrategies, MultiParamTypeClasses, FunctionalDependencies, GeneralizedNewtypeDeriving #-}
import Data.Kind
import Data.Functor.Identity
class SIEVE f p | p -> f where
sIEVE :: p a b -> a -> f b
instance SIEVE Identity (->) where
sIEVE = (Identity .)
newtype ARR a b = ARR (a -> b)
deriving newtype
(SIEVE Identity)
```
But what if I want a `Sieve I ARR` instance, for `newtype I a = I a` (which is representationally equal to `newtype Identity a = Identity a`)?
```hs
{-# Language DerivingStrategies, MultiParamTypeClasses, FunctionalDependencies, GeneralizedNewtypeDeriving, RankNTypes, TypeApplications, ScopedTypeVariables, InstanceSigs #-}
import Data.Kind
import Data.Functor.Identity
import Data.Coerce
class SIEVE f p | p -> f where
sIEVE :: p a b -> a -> f b
instance SIEVE Identity (->) where
sIEVE = (Identity .)
newtype ARR a b = ARR (a -> b)
deriving newtype
(SIEVE I)
newtype I a = I a
```
generating the following code (this is basically to code generated before, except replacing some `Identity`s with `I`s
```hs
instance SIEVE I ARR where
sIEVE :: forall a b. ARR a b -> (a -> I b)
sIEVE
= coerce
@((a -> b) -> a -> Identity b)
@(ARR a b -> a -> I b)
sIEVE
```
GHC should be able to recover `Identity` due to the functional dependency.https://gitlab.haskell.org/ghc/ghc/-/issues/13748Variables pretty-printed from -ddump-deriv are not scoped properly2019-07-07T18:20:17ZRyan ScottVariables pretty-printed from -ddump-deriv are not scoped properlyThis bug is present on GHC 8.0.1, 8.0.2, 8.2.1 and HEAD, and originally noted in #13738\##13748. Take this code:
```hs
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
{-# LANGUAGE PolyKinds #-}
{-# OPTIONS_GHC -ddump-deriv #-}
module Works ...This bug is present on GHC 8.0.1, 8.0.2, 8.2.1 and HEAD, and originally noted in #13738\##13748. Take this code:
```hs
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
{-# LANGUAGE PolyKinds #-}
{-# OPTIONS_GHC -ddump-deriv #-}
module Works where
newtype Wrap f a = Wrap (f a) deriving C
class C f where
c :: f a
```
When you compile it with GHC 8.0.2, you'll get this unsavory output:
```
GHCi, version 8.0.2: http://www.haskell.org/ghc/ :? for help
Loaded GHCi configuration from /home/rgscott/.ghci
[1 of 1] Compiling Works ( Works.hs, interpreted )
==================== Derived instances ====================
Derived instances:
instance forall k_a14U (f_a14V :: k_a14U -> *).
Works.C f_a14V =>
Works.C (Works.Wrap f_a14V) where
Works.c
= GHC.Prim.coerce
@(forall (a_a13F :: k_a14u). f_a13G a_a13F)
@(forall (a_a13F :: k_a14u). Works.Wrap f_a13G a_a13F)
Works.c
GHC.Generics representation types:
```
This is wrong, since the quantified variables in the instance head (`k_a14U` and `f_a14V`) do not match the occurrences that they bind (`k_a14u` and `f_a13G`). This is somewhat easier to see on GHC 8.2.1 or HEAD, since the binding sites are printed without uniques:
```
GHCi, version 8.3.20170516: http://www.haskell.org/ghc/ :? for help
Loaded GHCi configuration from /home/rgscott/.ghci
[1 of 1] Compiling Works ( Works.hs, interpreted )
==================== Derived instances ====================
Derived class instances:
instance forall k (f :: k -> *).
Works.C f =>
Works.C (Works.Wrap f) where
Works.c
= GHC.Prim.coerce
@(forall (a_a1tD :: k_a1uE). f_a1tE a_a1tD)
@(forall (a_a1tD :: k_a1uE). Works.Wrap f_a1tE a_a1tD)
Works.c
Derived type family instances:
```
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | ----------------------- |
| Version | 8.0.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":"Variables pretty-printed from -ddump-deriv are not scoped properly","status":"New","operating_system":"","component":"Compiler (Type checker)","related":[],"milestone":"","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"8.0.1","keywords":[],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"Bug","description":"This bug is present on GHC 8.0.1, 8.0.2, 8.2.1 and HEAD, and originally noted in https://ghc.haskell.org/trac/ghc/ticket/13738#comment:2. Take this code:\r\n\r\n{{{#!hs\r\n{-# LANGUAGE GeneralizedNewtypeDeriving #-}\r\n{-# LANGUAGE PolyKinds #-}\r\n{-# OPTIONS_GHC -ddump-deriv #-}\r\nmodule Works where\r\n\r\nnewtype Wrap f a = Wrap (f a) deriving C\r\n\r\nclass C f where\r\n c :: f a\r\n}}}\r\n\r\nWhen you compile it with GHC 8.0.2, you'll get this unsavory output:\r\n\r\n{{{\r\nGHCi, version 8.0.2: http://www.haskell.org/ghc/ :? for help\r\nLoaded GHCi configuration from /home/rgscott/.ghci\r\n[1 of 1] Compiling Works ( Works.hs, interpreted )\r\n\r\n==================== Derived instances ====================\r\nDerived instances:\r\n instance forall k_a14U (f_a14V :: k_a14U -> *).\r\n Works.C f_a14V =>\r\n Works.C (Works.Wrap f_a14V) where\r\n Works.c\r\n = GHC.Prim.coerce\r\n @(forall (a_a13F :: k_a14u). f_a13G a_a13F)\r\n @(forall (a_a13F :: k_a14u). Works.Wrap f_a13G a_a13F)\r\n Works.c\r\n \r\n\r\nGHC.Generics representation types:\r\n}}}\r\n\r\nThis is wrong, since the quantified variables in the instance head (`k_a14U` and `f_a14V`) do not match the occurrences that they bind (`k_a14u` and `f_a13G`). This is somewhat easier to see on GHC 8.2.1 or HEAD, since the binding sites are printed without uniques:\r\n\r\n{{{\r\nGHCi, version 8.3.20170516: http://www.haskell.org/ghc/ :? for help\r\nLoaded GHCi configuration from /home/rgscott/.ghci\r\n[1 of 1] Compiling Works ( Works.hs, interpreted )\r\n\r\n==================== Derived instances ====================\r\nDerived class instances:\r\n instance forall k (f :: k -> *).\r\n Works.C f =>\r\n Works.C (Works.Wrap f) where\r\n Works.c\r\n = GHC.Prim.coerce\r\n @(forall (a_a1tD :: k_a1uE). f_a1tE a_a1tD)\r\n @(forall (a_a1tD :: k_a1uE). Works.Wrap f_a1tE a_a1tD)\r\n Works.c\r\n \r\n\r\nDerived type family instances:\r\n}}}","type_of_failure":"OtherFailure","blocking":[]} -->https://gitlab.haskell.org/ghc/ghc/-/issues/13731DeriveFunctor and friends don't understand type families2020-06-08T17:11:37ZSophie TaylorDeriveFunctor and friends don't understand type families```hs
{-# LANGUAGE DeriveFunctor #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE GADTs #-}
{-# LANGUAGE StandaloneDeriving #-}
{-# LANGUAGE TypeFamilies #-}
data Test ext a where
Foo :: a -> Test ext a
Extend :: (ExtensionType e...```hs
{-# LANGUAGE DeriveFunctor #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE GADTs #-}
{-# LANGUAGE StandaloneDeriving #-}
{-# LANGUAGE TypeFamilies #-}
data Test ext a where
Foo :: a -> Test ext a
Extend :: (ExtensionType ext a) -> Test ext a
type family ExtensionType ext a
data ListExtension
type instance ExtensionType ListExtension a = [a]
deriving instance Functor (Test ListExtension)
{-
a.hs:15:1: error:
• Can't make a derived instance of ‘Functor (Test ListExtension)’:
Constructor ‘Extend’ must use the type variable only as the last argument of a data type
• In the stand-alone deriving instance for
‘Functor (Test ListExtension)’
|
15 | deriving instance Functor (Test ListExtension)
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Failed, modules loaded: none.
-}
```
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | ------------ |
| Version | 8.2.1-rc2 |
| 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":"DeriveFunctor and friends don't understand type families","status":"New","operating_system":"","component":"Compiler","related":[],"milestone":"","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"8.2.1-rc2","keywords":[],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"Bug","description":"{{{#!hs\r\n{-# LANGUAGE DeriveFunctor #-}\r\n{-# LANGUAGE FlexibleInstances #-}\r\n{-# LANGUAGE GADTs #-}\r\n{-# LANGUAGE StandaloneDeriving #-}\r\n{-# LANGUAGE TypeFamilies #-}\r\n\r\ndata Test ext a where\r\n Foo :: a -> Test ext a\r\n Extend :: (ExtensionType ext a) -> Test ext a\r\n\r\ntype family ExtensionType ext a\r\ndata ListExtension\r\ntype instance ExtensionType ListExtension a = [a]\r\n\r\nderiving instance Functor (Test ListExtension)\r\n\r\n{-\r\n\r\na.hs:15:1: error:\r\n • Can't make a derived instance of ‘Functor (Test ListExtension)’:\r\n Constructor ‘Extend’ must use the type variable only as the last argument of a data type\r\n • In the stand-alone deriving instance for\r\n ‘Functor (Test ListExtension)’\r\n |\r\n15 | deriving instance Functor (Test ListExtension)\r\n | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\r\nFailed, modules loaded: none.\r\n-}\r\n}}}","type_of_failure":"OtherFailure","blocking":[]} -->https://gitlab.haskell.org/ghc/ghc/-/issues/13465Foldable deriving treatment of tuples is too surprising2020-01-23T19:31:53ZDavid FeuerFoldable deriving treatment of tuples is too surprising```
*> :set -XDeriveFoldable
*> data Foo a = Foo ((a,a),a) deriving Foldable
*> length ((1,1),1)
1 ...```
*> :set -XDeriveFoldable
*> data Foo a = Foo ((a,a),a) deriving Foldable
*> length ((1,1),1)
1
*> length $ Foo ((1,1),1)
3
```
I think the right thing is probably to refuse to derive `Foldable` if components of a tuple other than the last one may contain the type variable we're looking for.
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | ------------ |
| Version | 8.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":"Foldable deriving treatment of tuples is too surprising","status":"New","operating_system":"","component":"Compiler","related":[],"milestone":"8.4.1","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"8.1","keywords":[],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"Bug","description":"{{{\r\n*> :set -XDeriveFoldable\r\n*> data Foo a = Foo ((a,a),a) deriving Foldable \r\n*> length ((1,1),1)\r\n1 \r\n*> length $ Foo ((1,1),1)\r\n3 \r\n}}}\r\n\r\nI think the right thing is probably to refuse to derive `Foldable` if components of a tuple other than the last one may contain the type variable we're looking for.","type_of_failure":"OtherFailure","blocking":[]} -->https://gitlab.haskell.org/ghc/ghc/-/issues/13403Derive instances (Applicative, Monad, ...) for structures lifted over functors2019-07-07T18:22:02ZIcelandjackDerive instances (Applicative, Monad, ...) for structures lifted over functorsI'll start small: Given that we know how to define various instances for [Product](https://hackage.haskell.org/package/base-4.9.1.0/docs/Data-Functor-Product.html) GHC could do it automatically.
```hs
data P f g a = f a ::: g a deriving...I'll start small: Given that we know how to define various instances for [Product](https://hackage.haskell.org/package/base-4.9.1.0/docs/Data-Functor-Product.html) GHC could do it automatically.
```hs
data P f g a = f a ::: g a deriving (Functor, Applicative, Alternative)
{-
instance (Applicative f, Applicative g) => Applicative (P f g) where
pure x = pure x ::: pure x
(f:::g) <*> (x:::y) = (f <*> x) ::: (g <*> y)
-}
```
And for specific constructors as well
```hs
data Q a = [a] :*: Maybe a deriving (Functor, Applicative, Alternative)
{-
instance Applicative Q where
pure x = [x] :*: Just x
(f:*:g) <*> (x:*:y) = (f <*> x) :*: (g <*> y)
-}
```
## Alternative
Use `GeneralizedNewtypeDeriving`
```hs
newtype Q a = Q (Product [] Maybe a)
deriving (Functor, Applicative, Alternative)
pattern (:*:) :: [a] -> Maybe a -> Q a
pattern a :*: b = Q (Pair a b)
```
## Future Work
This should work for a combination of various things, using `Const _` deprives us of `Alternative`
```hs
newtype U e a = U (([] `Product` Maybe `Product` Const e) a)
deriving (Functor, Applicative)
```
using sums where [one summand is identity](https://hackage.haskell.org/package/transformers-0.5.4.0/docs/Control-Applicative-Lift.html) gives us `Applicative` / `Alternative`
```hs
-- data Lift f a = Pure a | Other (f a)
import Control.Applicative.Lift
data V a = V ((Lift [] `Product` Maybe) a)
deriving (Functor, Applicative, Alternative)
```
I want to be able to write this directly
```hs
data U e a = U [a] (Maybe a) (Const e a)
deriving (Functor, Applicative)
data V a
= VL a (Maybe a)
| VR [a] (Maybe a)
deriving (Functor, Applicative, Alternative)
```
## Future, Future Work ==
[left-Kan extension](https://hackage.haskell.org/package/kan-extensions-5.0.1/docs/Data-Functor-Kan-Lan.html)
```hs
data Lan g h a where
Lan :: (g b -> a) -> h b -> Lan g h a
deriving (Functor, Applicative)
```
[codensity](https://hackage.haskell.org/package/kan-extensions-5.0.1/docs/Control-Monad-Codensity.html)
```hs
data Endo a = Endo (a -> a)
newtype CodEndo a = CE (forall xx. (a -> Endo xx) -> Endo xx)
deriving (Functor, Applicative, Monad)
```
and [comonad](https://hackage.haskell.org/package/free-4.12.4/docs/Control-Comonad-Cofree.html)
```hs
data Rose a = a :< [Rose a]
deriving (Functor, Applicative, Monad, Comonad, ...)
```
<details><summary>Trac metadata</summary>
| Trac field | Value |
| ---------------------- | ------------ |
| Version | 8.0.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":"Derive instances (Applicative, Monad, ...) for structures lifted over functors","status":"New","operating_system":"","component":"Compiler","related":[],"milestone":"","resolution":"Unresolved","owner":{"tag":"Unowned"},"version":"8.0.1","keywords":[],"differentials":[],"test_case":"","architecture":"","cc":[""],"type":"Bug","description":"I'll start small: Given that we know how to define various instances for [https://hackage.haskell.org/package/base-4.9.1.0/docs/Data-Functor-Product.html Product] GHC could do it automatically.\r\n\r\n{{{#!hs\r\ndata P f g a = f a ::: g a deriving (Functor, Applicative, Alternative)\r\n\r\n{-\r\ninstance (Applicative f, Applicative g) => Applicative (P f g) where\r\n pure x = pure x ::: pure x\r\n (f:::g) <*> (x:::y) = (f <*> x) ::: (g <*> y)\r\n-}\r\n}}}\r\n\r\nAnd for specific constructors as well\r\n\r\n{{{#!hs\r\ndata Q a = [a] :*: Maybe a deriving (Functor, Applicative, Alternative)\r\n\r\n{-\r\ninstance Applicative Q where\r\n pure x = [x] :*: Just x\r\n (f:*:g) <*> (x:*:y) = (f <*> x) :*: (g <*> y)\r\n-}\r\n}}}\r\n\r\n== Alternative ==\r\n\r\nUse `GeneralizedNewtypeDeriving`\r\n\r\n{{{#!hs\r\nnewtype Q a = Q (Product [] Maybe a)\r\n deriving (Functor, Applicative, Alternative)\r\n\r\npattern (:*:) :: [a] -> Maybe a -> Q a\r\npattern a :*: b = Q (Pair a b)\r\n}}}\r\n\r\n== Future Work ==\r\n\r\nThis should work for a combination of various things, using `Const _` deprives us of `Alternative`\r\n\r\n{{{#!hs\r\nnewtype U e a = U (([] `Product` Maybe `Product` Const e) a)\r\n deriving (Functor, Applicative)\r\n}}}\r\n\r\nusing sums where [https://hackage.haskell.org/package/transformers-0.5.4.0/docs/Control-Applicative-Lift.html one summand is identity] gives us `Applicative` / `Alternative`\r\n\r\n{{{#!hs\r\n-- data Lift f a = Pure a | Other (f a)\r\nimport Control.Applicative.Lift\r\n\r\ndata V a = V ((Lift [] `Product` Maybe) a) \r\n deriving (Functor, Applicative, Alternative)\r\n}}}\r\n\r\nI want to be able to write this directly\r\n\r\n{{{#!hs\r\ndata U e a = U [a] (Maybe a) (Const e a)\r\n deriving (Functor, Applicative)\r\n\r\ndata V a\r\n = VL a (Maybe a)\r\n | VR [a] (Maybe a)\r\n deriving (Functor, Applicative, Alternative)\r\n}}}\r\n\r\n== Future, Future Work == \r\n\r\n[https://hackage.haskell.org/package/kan-extensions-5.0.1/docs/Data-Functor-Kan-Lan.html left-Kan extension]\r\n\r\n{{{#!hs\r\ndata Lan g h a where\r\n Lan :: (g b -> a) -> h b -> Lan g h a\r\n deriving (Functor, Applicative)\r\n}}}\r\n\r\n[https://hackage.haskell.org/package/kan-extensions-5.0.1/docs/Control-Monad-Codensity.html codensity]\r\n\r\n{{{#!hs\r\ndata Endo a = Endo (a -> a)\r\n\r\nnewtype CodEndo a = CE (forall xx. (a -> Endo xx) -> Endo xx)\r\n deriving (Functor, Applicative, Monad)\r\n}}}\r\n\r\nand [https://hackage.haskell.org/package/free-4.12.4/docs/Control-Comonad-Cofree.html comonad]\r\n\r\n{{{#!hs\r\ndata Rose a = a :< [Rose a]\r\n deriving (Functor, Applicative, Monad, Comonad, ...)\r\n}}}","type_of_failure":"OtherFailure","blocking":[]} -->