Je peux écrire ce qui suit:contraintes Contraindre
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE UndecidableInstances #-}
{-# LANGUAGE ConstraintKinds #-}
f :: Integral a => (forall b. Num b => b) -> a
f = id
Et tout est bon. Vraisemblablement GHC peut dériver Integral
de Num
alors tout va bien.
Je peux être un peu Tricker, mais je suis toujours très bien:
class Integral x => MyIntegral x
instance Integral x => MyIntegral x
class Num x => MyNum x
instance Num x => MyNum x
f' :: MyIntegral a => (forall b. MyNum b => b) -> a
f' = id
permet donc de dire que je veux généraliser cela, comme ceci:
g :: c2 a => (forall b. c1 b => b) -> a
g = id
Maintenant, évidemment, cela va cracher le factice, car GHC ne peut pas dériver c2
de c1
, comme c2
n'est pas contraint.
Que dois-je ajouter à la signature de type g
pour dire que "vous pouvez dériver c2
de c1
"?
Quand vous dites "dériver X à partir de Y", je dirais plutôt "dériver Y à partir de X". Dans votre premier exemple, nous avons que 'Integral t' implique' Num t', et non l'inverse. GHC doit extraire un dictionnaire 'Num' à partir du dictionnaire' Integral 'passé. Et de même pour les autres cas que vous mentionnez ci-dessous. – chi