2017-06-28 6 views
1

Je tente d'écrire un wrapper fin autour de repa pour fournir des contraintes supplémentaires pour certains travaux spécifiques au domaine que je fais. J'ai le type:Types internes variables pour le tableau Repa enveloppé

newtype Tile p r a = Tile { _array :: Array r DIM2 a } 

Array vient de repa. Je voudrais cacher la r car il ajoute du bruit au type signatures et fait Tile une abstraction qui fuit:

newtype Tile p a = Tile { _array :: Array ? DIM2 a } -- what should `?` be? 

Malheureusement, ce r peut changer entre les opérations de repa. La plupart du temps c'est D (pour "représentation différée"), mais quand les données sont créées à partir d'une liste ou d'un vecteur, ce serait U ("vecteur non boxé") ou V ("vector boxed"). Ceux-ci sont utilisés comme conseils de type pour aider le personnel à optimiser ses opérations.

Y a-t-il un moyen pour moi de masquer le r comme je voudrais, mais permettez-lui de varier naturellement en interne sans affecter le typochecking avec mon type de wrapper Tile? Est-ce le domaine de RankNTypes et amis? Je reconnais que je ne les comprends pas très bien. Pour être le plus clair, je voudrais pouvoir écrire:

foo :: Tile p a -> Tile p b -> Tile p c

où les deux arguments Tile contiennent (par exemple) un Array U DIM2 Int et Array D DIM2 Int respectivement. Est-ce une mauvaise chose à désirer?

+0

Vous devrez utiliser une déclaration 'data' réelle, mais vous pouvez faire' data Tile p a = forall d. Mosaïque {_array :: Array d Dim2 a} '. – Alec

+0

C'est plus proche de ce dont j'ai besoin, ouais. Mais woops, s'avère que 'd' a des contraintes de typeclass ailleurs: S –

+0

Vous pouvez également mettre les contraintes dans la déclaration' data'. 'data Showable = pour tout a. Montrer a => SomeShow a'. – Alec

Répondre

1

J'ai réussi à contourner le problème en forçant le Array enveloppé à toujours contenir le type D en utilisant le delay function. Cela m'a également permis de conserver Tile comme newtype et de définir également une instance Functor pour cela.