Open tomjaguarpaw opened 6 years ago
genericAdaptor
here takes type genericAdaptor :: (String -> String, [Integer -> Integer]) -> (String, Integer) -> c
, and the constraints deduce Rep c
but that is not sufficient to deduce c
itself since Rep
is not an injective family.
It looks like instead of a -> p b c
we should use Adaptor p a
, which is less general but has better inference.
Great, thanks! I would indeed prefer this to be less general. I really want it to only work with types that look like Foo (p a b) (p a' b') -> p (Foo a b) (Foo a' b')
. Your formulation via Adaptor p a
has the properties that if we know a
we know
p
via the fundep on GAdaptor
,b
by the type family Unzip 'Fst
, andc
by the type family Unzip 'Snd
Is there any hope of going the other way?
Oh, it doesn't seem to work, actually.
> genericAdaptor (("hello " ++), reverse) ("world", [1..5])
<interactive>:10:1:
Could not deduce (Unzip 'Fst (,) ~ (,))
from the context (Enum t,
Num t,
GHC.Generics.Generic (Unzip 'Fst (,) [Char] [t]),
GHC.Generics.Generic (Unzip 'Snd (,) [Char] [t]),
GHC.Generics.Rep (Unzip 'Fst (,) [Char] [t])
~ GHC.Generics.M1
GHC.Generics.D
GHC.Generics.D1(,)
(GHC.Generics.M1
GHC.Generics.C
GHC.Generics.C1_0(,)
(GHC.Generics.M1
GHC.Generics.S
GHC.Generics.NoSelector
(GHC.Generics.K1 GHC.Generics.R [Char])
GHC.Generics.:*: GHC.Generics.M1
GHC.Generics.S
GHC.Generics.NoSelector
(GHC.Generics.K1 GHC.Generics.R [t]))),
GHC.Generics.Rep (Unzip 'Snd (,) [Char] [t])
~ GHC.Generics.M1
GHC.Generics.D
GHC.Generics.D1(,)
(GHC.Generics.M1
GHC.Generics.C
GHC.Generics.C1_0(,)
(GHC.Generics.M1
GHC.Generics.S
GHC.Generics.NoSelector
(GHC.Generics.K1 GHC.Generics.R [Char])
GHC.Generics.:*: GHC.Generics.M1
GHC.Generics.S
GHC.Generics.NoSelector
(GHC.Generics.K1 GHC.Generics.R [t]))))
bound by the inferred type of
it :: (Enum t, Num t,
GHC.Generics.Generic (Unzip 'Fst (,) [Char] [t]),
GHC.Generics.Generic (Unzip 'Snd (,) [Char] [t]),
GHC.Generics.Rep (Unzip 'Fst (,) [Char] [t])
~ GHC.Generics.M1
GHC.Generics.D
GHC.Generics.D1(,)
(GHC.Generics.M1
GHC.Generics.C
GHC.Generics.C1_0(,)
(GHC.Generics.M1
GHC.Generics.S
GHC.Generics.NoSelector
(GHC.Generics.K1 GHC.Generics.R [Char])
GHC.Generics.:*: GHC.Generics.M1
GHC.Generics.S
GHC.Generics.NoSelector
(GHC.Generics.K1 GHC.Generics.R [t]))),
GHC.Generics.Rep (Unzip 'Snd (,) [Char] [t])
~ GHC.Generics.M1
GHC.Generics.D
GHC.Generics.D1(,)
(GHC.Generics.M1
GHC.Generics.C
GHC.Generics.C1_0(,)
(GHC.Generics.M1
GHC.Generics.S
GHC.Generics.NoSelector
(GHC.Generics.K1 GHC.Generics.R [Char])
GHC.Generics.:*: GHC.Generics.M1
GHC.Generics.S
GHC.Generics.NoSelector
(GHC.Generics.K1 GHC.Generics.R [t])))) =>
Unzip 'Snd (,) [Char] [t]
at <interactive>:10:1-57
Expected type: ([Char], [t]) -> Unzip 'Snd (,) [Char] [t]
Actual type: Unzip 'Fst ([Char] -> [Char], [t] -> [t])
-> Unzip 'Snd ([Char] -> [Char], [t] -> [t])
The function ‘genericAdaptor’ is applied to two arguments,
its type is ‘Adaptor p0 a0’,
it is specialized to ‘Adaptor (->) ([Char] -> [Char], [t] -> [t])’
In the expression:
genericAdaptor (("hello " ++), reverse) ("world", [1 .. 5])
In an equation for ‘it’:
it = genericAdaptor (("hello " ++), reverse) ("world", [1 .. 5])
It seems instances of Unzippable
(which defines Unzip
) are missing for the standard types, which would cause that error for GHC < 8.
instance Unzippable (,)
@hesselink I have hit a snag with
genericAdaptor
. It does not infer properly. For example, if I usep2
I get nice inference behaviourOn the other hand, using
genericAdaptor
for the same purpose gives the error shown at the bottom of this comment. I managed to add a functional dependency which ends up giving us essentiallya -> p
. I think what we need isa -> p b c, p b c -> a
. I can't see how to achieve this becauseRep
seems to get in the way.Do you have any ideas how to address this? @Lysxia, you may also have some clever idea. about this.
Thanks!
genericAdaptor
type error: