Mi chiedo se non ci sia una ragione più profonda per cui non possiamo astrarre le classi di tipi (o possiamo?).Potremmo astrarre oltre le classi di tipi?
Per esempio, quando abbiamo
fzip :: (forall a.[a] -> [a]) -> [b] -> [c] -> [(b,c)]
fzip f xs ys = zip (f xs) (f ys)
allora possiamo dire
fzip (drop 42) [1..100] ['a'..'z']
fzip reverse [1..100] ['a'..'z']
e così via. Ma non possiamo
fzip (map succ) [1..100] ['a'..'z']
che possiamo risolvere con:
ezip :: (Enum b, Enum c) => (forall a.Enum a => [a] -> [a]) -> [b] -> [c] -> [(b,c)]
ezip f xs ys = zip (f xs) (f ys)
e allo stesso modo siamo in grado di risolvere
fzip (map (5*)) [1..100] [1.5, 2.3, 4.7]
con
nzip :: (Num b, Num c) => (forall a.Num a => [a] -> [a]) -> [b] -> [c] -> [(b,c)]
nzip f xs ys = zip (f xs) (f ys)
Ma non è imbarazzante che abbiamo non può sussumere lo ezip
e nzip
con qualcosa di simile:
gzip :: (g b, g c) => (forall a. g a => [a] -> [a]) -> [b] -> [c] -> [(b,c)]
se il codice è assolutamente identica, fino al nome della classe? Oppure possiamo in qualche modo?
È interessante notare che quando le istanze erano solo record che contenevano funzioni, ciò sarebbe facilmente possibile.
Il sistema 'Constraint' di GHC si aspetta che la risolvibilità sia * decidibile in modo monomorfico (nel senso che tutti i tipi con tipo' Constraint' sono previsti da uno o più tipi _known_ - cioè, una classe superiore di typeclass non può essere variadic nell'intestazione typeclass) , Penso che potrebbe essere un vantaggio –