2013-12-09 15 views
8

Tôi có một loại mà về cơ bản đóng vai trò như một thẻ trên một loại dữ liệu:"Kế thừa" thể hiện của kiểu quấn

import Data.Word 
data RijndaelField = RF Word8 

Tôi muốn RijndaelField để "kế thừa" những Word8 thể hiện của Bits theo cách đơn giản nhất có thể:

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 

Có cách nào ngắn hơn để thể hiện mối quan hệ đó giữa RijndaelFieldWord8 không?

Trả lời

12

Nếu bạn không cần ADTs hoặc các loại hồ sơ, bạn có thể sử dụng một newtype thay vì với GeneralizedNewtypeDeriving:

{-# LANGUAGE GeneralizedNewtypeDeriving #-} 

import Data.Bits 
import Data.Word 

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

Nếu bạn thực sự muốn, bạn có thể bao gồm rất nhiều các lớp khác

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

nào sẽ cho phép bạn sử dụng nó như

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

Tôi cho rằng nó khá tiện dụng

+0

Đó chính xác là những gì tôi đang tìm kiếm, cảm ơn bạn. (Có một phần mở rộng cho tất cả mọi thứ!) – Snowball

+0

@Snowball Chỉ khoảng =) Cái này đặc biệt hữu ích khi gói lên một chồng máy biến áp đơn, bạn có thể có trình biên dịch lấy được những thứ như 'Monad',' Functor', 'MonadTrans',' MonadState MyState', 'Applicative' và hơn thế nữa. Nó rất tiện dụng để tạo ra rất nhiều mã soạn sẵn. – bheklilr