2013-12-09 10 views
8

ich einen Typ haben, die im Grunde als Tag auf einen anderen Datentyp wirkt:„Vererben“ Instanz von umschlossenen Typ

import Data.Word 
data RijndaelField = RF Word8 

Ich möchte RijndaelField, um die Word8 Instanz Bits auf einfachste Weise „erben“ möglich:

import Data.Bits 
instance Bits RijndaelField where 
    RF a .&. RF b  = RF $ a .&. b 
    RF a .|. RF b  = RF $ a .|. b 
    RF a `xor` RF b = RF $ a `xor` b 
    complement (RF a) = RF $ complement a 
    shift (RF a) n = RF $ shift a n 
    rotate (RF a) n = RF $ rotate a n 
    bitSize (RF a) = bitSize a 
    isSigned (RF a) = isSigned a 
    testBit (RF a) n = testBit a n 
    bit n    = RF $ bit n 
    popCount (RF a) = popCount a 

gibt es einen kürzeren Weg, dass die Beziehung zwischen RijndaelField und Word8 zum Ausdruck bringen?

Antwort

12

Wenn Sie ADTs oder Datensatztypen nicht benötigen, können Sie ein newtype verwenden, anstatt mit GeneralizedNewtypeDeriving:

{-# LANGUAGE GeneralizedNewtypeDeriving #-} 

import Data.Bits 
import Data.Word 

newtype RF = RF { unRF :: Word8 } deriving (Eq, Bits) 

Wenn Sie wirklich, wollte man

eine Menge anderer Klassen umfassen kann
newtype RF = RF { unRF :: Word8 } 
    deriving (Eq, Bits, Num, Integral, Real, Enum, Ord, Show) 

Welche würden Sie es als

verwenden
> 1 :: RF 
RF {unRF = 1} 
> [1..5] :: [RF] 
[RF {unRF = 1},RF {unRF = 2},RF {unRF = 3},RF {unRF = 4},RF {unRF = 5}] 
> let x = RF 1 
> x + 2 
RF {unRF = 3} 

Was ich denke, es ist sehr praktisch

+0

Das ist genau das, was ich gesucht habe, danke. (Es gibt eine Erweiterung für alles!) – Snowball

+0

@Snowball Gerade über =) Dies ist besonders nützlich, wenn Sie einen Stapel von Monade-Transformers umwickeln, können Sie den Compiler Dinge wie 'Monad',' Functor', 'MonadTrans',' ableiten lassen MonadState MyState', 'Applicative' und mehr. Es ist sehr praktisch, um eine Menge Code zu generieren. – bheklilr