Haskell Accessors for Non-Existing Entries

I am studying Haskell, and currently I am discovering "helpers" for data members. Suppose I have some kind of fictitious two-dimensional vertex information, one type that has some color, and the other has some texture coordinate (tc):

data SVertex = VertexC (Float, Float) Int
         | VertexTC (Float, Float) (Float, Float)
         deriving(Show)

One tedious way to create recording accessories is to write functions with templates:

position (VertexC (x,y) c ) = (x,y)
position (VertexTC (x,y) c ) = (x,y)
tc (VertexTC _ tc) = tc
color :: SVertex -> Int
color (VertexC _ c) = c

Now the positive feature is that I could add accessors (“color” and “tc”) for those that don't have “color” or “tc”:

position (VertexC (x,y) c ) = (x,y)
position (VertexTC (x,y) c ) = (x,y) -- no header, here... still works
tc (VertexTC _ tc) = tc
tc (VertexC _ _) = (0,0) -- to returns something even if the field doesn't exist
color :: SVertex -> Int
color (VertexC _ c) = c
color (VertexTC _ _) = 0 -- return something even if field doesn't exist

This allows me to assign default values ​​to 0 vertices that don't have texture coords or 0 colors at vertices that don't have color ... All is well ...

, : , . ( "prime", ):

data SVertex' = VertexC' {
    position'   :: (Float, Float),
    color'      :: Int
    }
    | VertexTC' {
    position'   :: (Float, Float),
    tc'         :: (Float, Float)
    } deriving(Show)

: "position", "tc" "color".

: , . , tc "VertexC"; VertexTC... . , . ,

color' (VertexTC' _ _) = 0

" " .. ". , , , ...

?

+4
1

, (.. ), , . - , , , SVertex . , , .

data VertexPaint = VertexC Int | VertexTC (Float, Float)
    deriving (Show)

data SVertex = SVertex
    { position :: (Float, Float)
    , paintjob :: VertexPaint
    } deriving (Show)

color, , . ( Maybe Int, , .)

color :: SVertex -> Maybe Int
color v = case paintjob v of
    VertexC c -> Just c
    VertexTC _ -> Nothing

, lens . , , .

+4

Source: https://habr.com/ru/post/1659957/


All Articles