Haskell type data range

I define my own data type.

data Row = A | B | C deriving (Show,Eq,Ord)

The question is, is there a more elegant way to define my range than this?

instance Ix Row where
  range (A,A) = [A]
  range (A,B) = [A,B]
  range (A,C) = [A,B,C]
  range (B,B) = [B]
  range (B,C) = [B,C]
  range (C,C) = [C]
  range _     = []
+4
source share
2 answers

Exists: Derive Enumand Define

range (x, y) = [x .. y]
+12
source

Using instance Enum

Yes, you can make an Rowinstance , in fact you do not need to define it yourself: Enum

data Row = A | B | C deriving (Show, Eq, Ord, Enum)

This means that we can now use the "range notation." For instance:

Prelude> [A .. C]
[A,B,C]
Prelude> [A .. B]
[A,B]
Prelude> [C .. B]
[]

So now we can define our instance Ixas:

instance Ix Row where
    range (x, z) = [x .. z]
    index (x, _) y = fromEnum y - fromEnum x
    inRange (x, z) y = x <= y && y <= z

Or even without parameters:

instance Ix Row where
    range = uncurry enumFromTo
    -- ...

Defining a custom successor function

Enum ( , , , ). , , :

instance Ix Row where
    range (x, z) = go x
        where go y | y > z = []
              go A = A : go B
              go B = B : go C
              go C = [C]

, - , , ( , ).

+10

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


All Articles