2013-12-09 4 views
8

У меня есть тип, который в основном действует в качестве метки на другой тип данных:«Наследование» экземпляр завернутые типа

import Data.Word 
data RijndaelField = RF Word8 

Я хочу RijndaelField на «унаследует» в Word8 экземпляр Bits в наиболее простым способом:

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 

есть ли более короткий путь, чтобы выразить, что соотношение между RijndaelField и Word8?

ответ

12

Если вам не нужны АТД или типы записей, вы можете использовать вместо newtype с GeneralizedNewtypeDeriving:

{-# LANGUAGE GeneralizedNewtypeDeriving #-} 

import Data.Bits 
import Data.Word 

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

Если вы действительно хотите, вы можете включать в себя много других классов

newtype RF = RF { unRF :: Word8 } 
    deriving (Eq, Bits, Num, Integral, Real, Enum, Ord, Show) 

Который позволил бы использовать его в качестве

> 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} 

Который я считаю весьма полезным

+0

Это именно то, что я искал, спасибо. (Существует расширение для всего!) – Snowball

+0

@Snowball Только около =) Это особенно полезно при упаковке стека монадных трансформаторов, вы можете заставить компилятор получить такие вещи, как «Monad», «Functor», «MonadTrans», MonadState MyState', 'Applicative' и многое другое. Это очень удобно для создания большого количества шаблонов. – bheklilr

Смежные вопросы