J'essaie de créer un wrapper newtype pour le type Linear.V et dériver des instances utiles. Je tentais ceci:Une erreur typecheck dans la dérivation wrapper pour Linear.V
{-# LANGUAGE DataKinds, PolyKinds, ScopedTypeVariables,
StandaloneDeriving, FlexibleContexts, UndecidableInstances,
GeneralizedNewtypeDeriving, PartialTypeSignatures, TypeFamilies #-}
import Linear.V
import Control.Lens.At
data Foo = Foo1 | Foo2 deriving (Show, Eq)
Tentative 1 - Je pense GeneralizedNewtypeDeriving ferait, mais Nope:
newtype Bar n = Bar {
getBar :: V n Foo
} deriving (Show, Eq, Ixed)
Je reçois cette erreur:
• Couldn't match representation of type ‘f (V n Foo)’
with that of ‘f (Bar n)’
arising from the coercion of the method ‘ix’
from type ‘Index (V n Foo)
-> Control.Lens.Type.Traversal' (V n Foo) (IxValue (V n Foo))’
to type ‘Index (Bar n)
-> Control.Lens.Type.Traversal' (Bar n) (IxValue (Bar n))’
NB: We cannot know what roles the parameters to ‘f’ have;
we must assume that the role is nominal
• When deriving the instance for (Ixed (Bar n))
J'ai fait essayer 2 en utilisant autonome dérivant comme ceci:
newtype Bar n = Bar {
getBar :: V n Foo
} deriving (Show, Eq)
type instance Index (Bar n) = Int
type instance IxValue (Bar n) = Foo
deriving instance Ixed (V n Foo) => Ixed (Bar n)
Mais j'ai eu une autre erreur:
• Couldn't match representation of type ‘f1 (V n Foo)’
with that of ‘f1 (Bar n)’
arising from a use of ‘GHC.Prim.coerce’
NB: We cannot know what roles the parameters to ‘f1’ have;
we must assume that the role is nominal
• In the expression:
GHC.Prim.coerce
@(Index (V n Foo)
-> Control.Lens.Type.Traversal' (V n Foo) (IxValue (V n Foo)))
@(Index (Bar n)
-> Control.Lens.Type.Traversal' (Bar n) (IxValue (Bar n)))
ix
In an equation for ‘ix’:
ix
= GHC.Prim.coerce
@(Index (V n Foo)
-> Control.Lens.Type.Traversal' (V n Foo) (IxValue (V n Foo)))
@(Index (Bar n)
-> Control.Lens.Type.Traversal' (Bar n) (IxValue (Bar n)))
ix
When typechecking the code for ‘ix’
in a derived instance for ‘Ixed (Bar n)’:
To see the code I am typechecking, use -ddump-deriv
In the instance declaration for ‘Ixed (Bar n)’
• Relevant bindings include
ix :: Index (Bar n)
-> Control.Lens.Type.Traversal' (Bar n) (IxValue (Bar n))
(bound at a.hs:12:1)
Je ne suis pas sûr pourquoi l'une des erreurs qui se passe réellement. Cela pourrait-il être fait d'une manière ou d'une autre? Je ne suis pas si expérimenté avec les fonctionnalités avancées de niveau de type et jusqu'à présent, je ne pouvais pas écrire cette définition d'instance en particulier, donc je considérerais cela comme une solution. Mais je préférerais utiliser le mécanisme deriving
d'une façon ou d'une autre, puisqu'il semble plus réutilisable.
EDIT: Je l'ai essayé exemple manuel decalaration:
type instance Index (Bar n) = Int
type instance IxValue (Bar n) = Foo
instance Ixed (Bar n) where
ix i f (Bar v) = ix i f v
Mais qui donnent l'erreur suivante:
• Couldn't match type ‘V n Foo’ with ‘Bar n’
Expected type: f (Bar n)
Actual type: f (V n Foo)
• In the expression: ix i f v
In an equation for ‘ix’: ix i f (Bar v) = ix i f v
In the instance declaration for ‘Ixed (Bar n)’
• Relevant bindings include
v :: V n Foo (bound at a.hs:14:15)
f :: IxValue (Bar n) -> f (IxValue (Bar n)) (bound at a.hs:14:8)
i :: Index (Bar n) (bound at a.hs:14:6)
ix :: Index (Bar n)
-> Control.Lens.Type.Traversal' (Bar n) (IxValue (Bar n))
(bound at a.hs:14:3)
Ce qui me semble comme que le compilateur ne peut pas comprendre que la Index
des deux V n Foo
et Bar n
est Int
. Mais je ne suis pas sûr de ça.
Merci, cela est solution acceptable pour moi. Je suppose qu'il a zéro frais généraux d'exécution, non? Y a-t-il encore un espoir de le faire en utilisant le mécanisme de «dérivation»? – user1747134
@ user1747134 C'est un nouveau type, donc je suppose que ça n'aura pas d'overhead. Je ne pense pas qu'il existe un moyen d'utiliser 'deriving'. – danidiaz