Saturday 30 April 2016

Haskell: View Patterns


View patterns are extensions to GHCi, By using view pattern, we can apply a function to a value and match the result against a pattern.

For example, I am going to develop an application for company ABC, There are three kinds of employees Engineer, Manager and Director. An Engineer is said to be special, if his name is “Hari” (or) id is 13.

Following function return the name of Engineer.
getName (Engineer name _) = name

Following function return id of engineer.
getId (Engineer _ empId) = empId

Following snippet, checks  whether Engineer is special (or) not.
isSpecialEngineer :: Employee -> Bool
isSpecialEngineer (getEngineerFirstName -> "Hari") = True
isSpecialEngineer (getEngineerId -> 13) = True
isSpecialEngineer _ = False

Let me try to explain this.
isSpecialEngineer :: Employee -> Bool
isSpecialEngineer (getEngineerFirstName -> "Hari") = True

getName is applied to an Engineer object and return True, if name is equal to “Hari”.

isSpecialEngineer (getId -> 13) = True
getId is applied to an Engineer object and return True, if the id is 13.

ViewPattern.hs
{-# LANGUAGE ViewPatterns #-}

module ABC where
    type Name = String
    type NoOfReportees = Integer
    type EngineerId = Integer
    type ManagerId = Integer
    type DirectorId = Integer

    {- Define an employee type -}
    data Employee = Engineer Name EngineerId
                   | Manager Name [EngineerId] ManagerId
                   | Director Name [ManagerId] DirectorId
                   deriving Show


    data Gender = Male | Female deriving Show

    getName :: Employee -> Name
    getName (Engineer name _) = name
    getName (Manager name _ _) = name
    getName (Director name _ _) = name

    getId :: Employee -> EngineerId
    getId (Engineer _ empId) = empId
    getId (Manager _ _ empId) = empId
    getId (Director _ _ empId) = empId

    isSpecialEngineer :: Employee -> Bool
    isSpecialEngineer (getName -> "Hari") = True
    isSpecialEngineer (getId -> 13) = True
    isSpecialEngineer _ = False

*ABC> :load ViewPattern.hs 
[1 of 1] Compiling ABC              ( ViewPattern.hs, interpreted )
Ok, modules loaded: ABC.
*ABC> 
*ABC> let engineer1 = Engineer "Hari" 123
*ABC> let engineer2 = Engineer "Krishna" 234
*ABC> let engineer3 = Engineer "Sudhir" 13
*ABC> 
*ABC> isSpecialEngineer engineer1
True
*ABC> isSpecialEngineer engineer2
False
*ABC> isSpecialEngineer engineer3
True
*ABC> 


Examples
a. Enginner is said to be special, if his id < 50.
Following snippet slove above problem.
isSpecialEngineer (getId -> x) | x < 50 = True
*ABC> let engineer3 = Engineer "Sudhir" 46
*ABC> isSpecialEngineer engineer3 
True
*ABC> 
*ABC> let engineer3 = Engineer "Sudhir" 436
*ABC> isSpecialEngineer engineer3 
False
*ABC> 


You can solve above problem by using following snippet also.
isSpecialEngineer (Engineer _ empId) | (empId < 50) = True

Exercise
a.   A Director is said to be special if his name is “Srinath” (or) “Suhas” (or) id is 321.
b.   A Manager is said to be special if his id < 35.

Note
If you are working on GHCi interpreter, you need to enable the view patterns, by using :set command.

Prelude> :set -XViewPatterns



Previous                                                 Next                                                 Home

No comments:

Post a Comment