Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Haskell: Understanding custom data types

I am trying to make my own custom data type in Haskell.

I have the following data types:

type Length = Integer 
type Rotation = Integer 
data Colour = Colour { red, green, blue, alpha :: Int }
            deriving (Show, Eq)

I am trying to make a custom data type that can be either one of the data types above. I have the following:

data Special 
  = L Length 
  | R Rotation 
  | Col Colour  
  deriving (Show, Eq) 

However, I would like to be able to extract the Length, Rotation and Colour value if I have an instance of the Special data type.

If I had:

L length

Would length here be of type Special or of type Length? If length is of type Special is there any way to extract it so it's of type Length?

For example, is the following code valid?

takeL (x:xs)
      | x == (L length) = length

Any insights are appreciated.

like image 455
ceno980 Avatar asked Jan 26 '23 02:01

ceno980


2 Answers

For the expression L length to be valid, length would have to be a Length (because L :: Length -> Special).

takeL (x:xs)
      | x == (L length) = length

is not valid. Unless you've redefined length somewhere, length is a function [a] -> Int from the standard library, so L length is a type error.

I think what you're trying to do here is just pattern matching:

takeL (L length : xs) = length
like image 155
melpomene Avatar answered Jan 29 '23 23:01

melpomene


The data type definition

data Special  = 

reads: Special is a new type such that to create a value of type Special,

                  L Length 
  • call L l where l is a value of type Length; or

                | R Rotation 
    
  • call R r where r is a value of type Rotation; or

                | Col Colour  
    
  • call Col c where c is a value of type Colour.


To analyze a value of type Special, there are three cases to consider:

foo :: Special -> ...
foo val = 
    case val of
        L   l -> ...  
  • l is a value of type Length, in the case val was actually L l; or

        R   r -> ... 
    
  • r is a value of type Rotation, in the case val was actually R r; or

        Col c -> ...  
    
  • c is a value of type Colour, in the case val was actually Col c.

The case syntax in function definitions can also be expressed with the pattern based clauses:

foo :: Special -> ...
foo (L   l) = ...
foo (R   r) = ...
foo (Col c) = ...
like image 45
Will Ness Avatar answered Jan 29 '23 23:01

Will Ness