2011-08-25 2 views
8

Je veux définir un type de "Ideal" qui est une liste mais avec une certaine structure. Le prélude numérique définit déjà les instances de Ring pour les listes, mais n'utilise pas les définitions d'addition et de multiplication que je souhaite. Je pense que dans ce cas, je devrais direHaskell newtype, mais conserve les anciennes fonctions

newtype Ideal a = Ideal [a] 

Cela fonctionne bien, mais maintenant il me donne une erreur si je tente de faire, dire take 5 $ Ideal [0..].

Y a-t-il un moyen de garder les fonctions que je veux et de ne remplacer que les définitions que je remplace explicitement?

Répondre

6

Pour les fonctions simples, pas. Vous devrez fournir vos propres définitions. Toutefois, pour les fonctions appartenant à une classe de type, vous pouvez utiliser l'extension GeneralizedNewtypeDeriving pour exposer les classes de type souhaitées à partir du type sous-jacent .

{-# LANGUAGE GeneralizedNewtypeDeriving #-} 
newtype MyState a = MyState (State Int a) 
    deriving (Monad) 
11

Si vous n'êtes pas trop fixé sur les choses étant complètement automatique, vous pouvez utiliser les fonctions d'utilité dans the newtype package, par exemple quelque chose comme over Ideal $ take 5.

Modifier: En outre, il n'est pas trop difficile d'étendre les fonctions du package newtype pour gérer d'autres cas. Par exemple, j'avais ces définitions qui traînent:

infixl 3 ./ 
(./) :: (Newtype n o) => (o -> t) -> (n -> t) 
(./) fx = fx . unpack 

liftN f x = pack $ f ./ x 
liftN2 f x y = pack $ f ./ x ./ y 
liftN3 f x y z = pack $ f ./ x ./ y ./ z 

Pas vraiment la meilleure conception pour ces combinateurs, je soupçonne, mais vous voyez l'idée.

Questions connexes