2009-11-29 3 views
13

Existe-t-il un moyen de "lever" facilement une instance de classe dans Haskell?Occurrence de classe de levage dans Haskell

J'ai souvent besoin de créer, par exemple, les instances Num pour certaines classes qui sont tout simplement « levage » la structure Num par le constructeur de type comme ceci:

data SomeType a = SomeCons a 

instance (Num a)=>Num SomeCons a where 
    (SomeCons x) + (SomeCons y) = SomeCons (x+y) 
    negate (SomeCons x) = SomeCons (negate x) 
    -- similarly for other functions. 

Y at-il un moyen d'éviter ce passe-partout et "soulevez" cette structure Num automatiquement? J'ai l'habitude de le faire avec Show et d'autres classes aussi quand j'essayais d'apprendre des existences et le compilateur ne me laissait pas utiliser deriving(Show).

Répondre

19

La newtype généralisée est l'extension dériver ce que vous voulez ici:

{-# LANGUAGE GeneralizedNewtypeDeriving #-} 

module Main where 

newtype SomeType a = SomeCons a deriving (Num, Show, Eq) 

main = do 
    let a = SomeCons 2 
     b = SomeCons 3 
    print $ a + b 

Sortie:

*Main> main 
SomeCons 5 
+1

Hum ... Pourquoi cela fonctionne avec newtype mais pas avec les données? –

+3

Étant donné qu'un newtype ne peut pas ajouter de constructeur ou de champ, il ne fait que réécrire un type existant. Cela garantit que l'extension peut fonctionner avec n'importe quelle classe, au lieu de seulement les classes que vous pouvez généralement obtenir pour n'importe quel type de données. – Martijn

5

GHC implémente ce que vous voulez: Extensions to the deriving mecanism. Ces modifications sont souvent indiquées pour l'extension future de la langue standard (Comme on le voit sur haskell' wiki)

Pour activer cette extension, vous devez utiliser le pragma suivant

{-# GeneralizedNewtypeDeriving #-} 

puis utiliser une dérivation sur votre déclaration newtype, comme d'habitude

data SomeType a = SomeCons a deriving (Num) 
1

GeneralizedNewtypeDeriving

Questions connexes