2013-12-09 2 views
8

나는 기본적으로 다른 데이터 유형에 대한 태그 역할을하는 유형이 있습니다는 포장 유형의 인스턴스를 "상속"

import Data.Word 
data RijndaelField = RF Word8 

내가 RijndaelField이 가능한 간단한 방법으로 BitsWord8 인스턴스를 "상속"할을 :

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 

RijndaelFieldWord8 사이의 관계를 표현하는 짧은 방법이 있나요?

답변

12

는 ADT를 또는 레코드 유형이 필요하지 않은 경우, 당신이 사용할 수있는 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 Just about =) 이것은 모나드 변환기의 스택을 감쌀 때 특히 유용합니다. 컴파일러가'Monad','Functor','MonadTrans', MonadState MyState','Applicative' 등이 있습니다. 많은 보편적 인 코드를 생성하는 데 매우 편리합니다. – bheklilr

관련 문제