You can define custom types in Haskell
using data, type, newtype declaration.
Declaration
|
Description
|
data
|
Define new data type
|
type
|
Give alternative names to existing
types
|
newtype
|
Define new types equivalent to
existing ones.
|
Syntax
to define custom type
data type tv1 ... tvi = con1 c1t1 c1t2... c1tn |
... | conm cmt1 ... cmtq
[deriving]
Define
custom types using data
Suppose you want to declare an Employee
type, which has properties like id, firstName, lastName, salary.
data Employee = Employee Int String
String Double
Above statement defines a custom data type
Employee. In Haskell, type names must start with a capital letter.
Type Constructor and value constructor
(also called data constructor) can have different names. Type constructor is
used in type declaration and type signatures, but value constructor is use in
actual code.
let emp1 = Employee 1 "Hari
Krishna" "Gurram" 12345.6
Above statement defines a variable emp1
with id 1, firstName "Hari Krishna", lastName "Gurram" and
salary 12345.6.
Prelude> data Employee = Employee Int String String Double Prelude> Prelude> :t Employee Employee :: Int -> String -> String -> Double -> Employee Prelude> Prelude> Prelude> let emp1 = Employee 1 "Hari Krishna" "Gurram" 12345.6
Algebraic
Data type
An algebraic data type can have more
than one value constructor associated with it. You can specify multiple constructors
for a custom type using | operator.
data Employee = Engineer Int String
String | Manager Int String String Double
Above statement declares new data type Employee,
which can be either an Engineer or a Manager. Engineer, Manager are the data constructors
for the type Employee. Where as Employee is called Type constructor. Engineer
contains one integer and two strings and a Manager contains one integer, two
strings and a double. The vertical bar separates the definitions of the two
possibilities.
Syntax
data NewDataType = Constructor1 Type11
Type12 .... Type1N
| Constructor2 Type21 Type22
.... Type2N
| Constructor3 Type31
Type32 .... Type3N
| Constructor4 Type41 Type42
.... Type4N
......
......
| ConstructorM Typem1 Typem2
.... TypemN
Here types for the constructors are
optional. Remember that types and constructor names must always start with
capital letter, variables and function names must always start with lower case
letter.
Prelude> data Employee = Engineer Int String String | Manager Int String String Double Prelude> Prelude> let emp1 = Engineer 1 "PTR" "Nayan" Prelude> let emp2 = Manager 1 "Sailaja" "Nayan" 9876543.12 Prelude> Prelude> :t emp1 emp1 :: Employee Prelude> Prelude> :t emp2 emp2 :: Employee Prelude> Prelude> :t Engineer Engineer :: Int -> String -> String -> Employee Prelude> Prelude> :t Manager Manager :: Int -> String -> String -> Double -> Employee
Extract contents of custom type
customType.hs
{-Define custom type-} data Employee = Engineer Int String String | Manager Int String String Double showBasicInfo id firstName lastName = "id = " ++ (show id) ++ " firstName = " ++ firstName ++ " lastName = " ++ lastName getEngineer (Engineer id firstName lastName) = showBasicInfo id firstName lastName getManager (Manager id firstName lastName salary) = showBasicInfo id firstName lastName ++ " salary = " ++ (show salary)
*Main> let engineer1 = Engineer 1 "Hari Krishna" "Gurram" *Main> *Main> let manager1 = Manager 2 "PTR" "Nayan" 12345678.90 *Main> *Main> getEngineer engineer1 "id = 1 firstName = Hari Krishna lastName = Gurram" *Main> *Main> getManager manager1 "id = 2 firstName = PTR lastName = Nayan salary = 1.23456789e7"
Above example shows how to extract
contents of custom type. I define two functions getEngineer, getManager. getEngineer
takes an Engineer type as an argument and return the Engineer details.
getManager function takes Manager type as an argument and return the Manager
details.
Function
Overloading
Function overloading is a feature, where
you can define a multiple functions with same name and different arguments. For
example, customType.hs is rewritten like below using function overloading.
customType.hs
{-Define custom type-} data Employee = Engineer Int String String | Manager Int String String Double showBasicInfo id firstName lastName = "id = " ++ (show id) ++ " firstName = " ++ firstName ++ " lastName = " ++ lastName getEmployee (Engineer id firstName lastName) = showBasicInfo id firstName lastName getEmployee (Manager id firstName lastName salary) = showBasicInfo id firstName lastName ++ " salary = " ++ (show salary)
*Main> let engineer1 = Engineer 1 "Hari Krishna" "Gurram" *Main> *Main> let manager1 = Manager 2 "PTR" "Nayan" 12345678.90 *Main> *Main> getEmployee engineer1 "id = 1 firstName = Hari Krishna lastName = Gurram" *Main> *Main> getEmployee manager1 "id = 2 firstName = PTR lastName = Nayan salary = 1.23456789e7"
Note
a. Types defined by data declarations are
often referred to as algebraic data types.
b. Types, constructors, type classes must
start with a capital letter.
No comments:
Post a Comment