How to handle many constants in Haskell?

Im working on a library that allows the developer to manage Minitel (French videotex).

I have many constant values, and I would like to know how to best manage them with Haskell. This is a common question among beginners, but I have not found a satisfying answer.

You can see my project (Note: yes, there are too many constants in one module that I am working on ;-))

I currently have modules supporting them both name = value. Although this works, I would like to know if it can be perfect or if I am doing the right thing.

aNUL = 0x00 -- Null
-- ...
aUS  = 0x1f -- Unit Separator

This method has a minor flaw: you cannot use pattern matching, you need to use protective devices if you want to keep the names:

completeReturn :: MString -> Bool
completeReturn []                 = False
completeReturn [0x19]             = False -- eSS2
completeReturn [0x1b, 0x5b, 0x32] = False -- eESC, eCSI, 0x32
completeReturn [0x1b, 0x5b, 0x34] = False -- eESC, eCSI, 0x34
completeReturn [0x19, 0x4b]       = False -- eSS2, 0x4b ; cedilla
completeReturn _                  = True

GHC, , GHC :

{-# OPTIONS_GHC -fno-warn-missing-signatures -fno-warn-type-defaults #-}

data deriving Enum, undefined, , 0. , , :

data ASCII = NUL -- ^ 0x00, Null
           -- ... 
           | US  -- ^ 0x1f, Unit Separator
           deriving (Enum, Show, Eq, Ord)

data C0 = NUL   -- ^ 0x00, NULl
        | Res01 -- ^ 0x01, undefined value
        -- ...
        | APA   -- ^ 0x1f, Activate Position Address
        deriving (Enum, Show, Eq, Ord)

data SSCFS = Res00 | Res01 | Res02 | Res03 | Res04 | Res05 | Res06 | Res07
           -- ...
           | Res38 | Res39 | Res3A | Res3B | Res3C | Res3D | Res3E | Res3F
           | ABK -- ^ 0x40, Alpha BlacK
           -- ...
           | RMS -- ^ 0x5f
           deriving (Enum, Show, Eq, Ord)

: :

codes = [ASCII.NUL, ASCII.SOH, C0.APB, C0.APF, 0x24] -- Error!

:

class Value a where
    value :: a -> Int

-- ASCII codes
data ASCII = NUL | SOH | STX | ETX {- ... -} deriving Show

instance Value ASCII where
    value NUL = 0
    value SOH = 1
    -- ...

-- C0 codes
data C0 = APB | APF | APD | APU {- ... -} deriving Show

instance Value C0 where
    value APB = 10
    value APF = 11
    -- ...

-- Mini type
data Mini = ASCII ASCII | C0 C0 | Literal Int deriving Show

instance Value Mini where
    value (ASCII code)  = value code
    value (C0 code)     = value code
    value (Literal int) = int

codes = [ASCII NUL, C0 APB, Literal 0x20]

main = do
    print (fmap value codes)

, . , NUL, SO SI ASCII, C0 ( , :-)). , ASCII . (ASCII ASCII.NUL).

?

+4
2

ghc 7.8, (. 7.3.8) . LANGUAGE -XPatternSynonyms.

{-# LANGUAGE PatternSynonyms #-}

pattern

pattern NUL = 0x00
pattern SSC = 0x19
pattern ESC = 0x1b
pattern US  = 0x1f
pattern CSI = 0x5b

.

type MString = [Int]

completeReturn :: MString -> Bool
completeReturn []                 = False
completeReturn [SSC]              = False -- eSS2
completeReturn [ESC , CSI , 0x32] = False -- eESC, eCSI, 0x32
completeReturn [ESC , CSI , 0x34] = False -- eESC, eCSI, 0x34
completeReturn [SSC , 0x4b]       = False -- eSS2, 0x4b ; cedilla
completeReturn _                  = True

, .

completeReturn [SSC]

, .

pattern EscCsi x = [ESC , CSI , x]

completeReturn :: MString -> Bool
completeReturn []                 = False
completeReturn [SSC]              = False -- eSS2
completeReturn (EscCsi 0x32)      = False -- eESC, eCSI, 0x32
completeReturn (EscCsi 0x34)      = False -- eESC, eCSI, 0x34
completeReturn [SSC , 0x4b]       = False -- eSS2, 0x4b ; cedilla
completeReturn _                  = True

.

completeReturn (EscCsi 0x7e)
+6

, ( - , ) - Enum, . , ASCII, ,

instance Enum ASCII where
  fromEnum a = case a of
    NUL -> 0x00
    ...
    US -> 0x1f
  toEnum a = case a of
    0x -> NUL
    0x1f -> US

Template Haskell, , -, , fromEnum toEnum.

+3

All Articles