Saturday, 30 April 2016

Haskell: functions: piece-wise definition


Suppose following are the points assigned to students based on their grade.
Grade
Points
1
10
2
9
3
8
4
4
5
3
6
2
7
1
8
0

By using if-else if-else  ladder, you can write the application like below.

getPoints.hs
getPoints :: Int -> Int
getPoints grade = 
    if grade == 1
        then
            10
    else if (grade == 2)
        then 
            9
    else if (grade == 3)
        then
            8
    else if (grade == 4)
        then
            4
    else if (grade == 5)
        then
            3
    else if (grade == 6)
        then
            2
    else if (grade == 7)
        then
            1
    else if (grade == 8)
        then
            0
    else
        -1

*Main> :load getPoints.hs
[1 of 1] Compiling Main             ( getPoints.hs, interpreted )
Ok, modules loaded: Main.
*Main> 
*Main> getPoints 1
10
*Main> getPoints 2
9
*Main> getPoints 3
8
*Main> getPoints 4
4
*Main> getPoints 5
3
*Main> getPoints 6
2
*Main> getPoints 7
1
*Main> getPoints 8
0
*Main> getPoints 9
-1
*Main> getPoints (-10)
-1


Same program can be written using guards like below.

getpoints_guards.hs
getPointsFromGrade :: Int -> Int
getPointsFromGrade grade
    | (grade == 1) = 10
    | (grade == 2) = 9
    | (grade == 3) = 8
    | (grade == 4) = 4
    | (grade == 5) = 3
    | (grade == 6) = 2
    | (grade == 7) = 1
    | (grade == 8) = 0
    | otherwise = -1

Prelude> :load getPoints_guards.hs
[1 of 1] Compiling Main             ( getPoints_guards.hs, interpreted )
Ok, modules loaded: Main.
*Main> 
*Main> getPointsFromGrade 1
10
*Main> getPointsFromGrade 2
9
*Main> getPointsFromGrade 3
8
*Main> getPointsFromGrade 4
4
*Main> getPointsFromGrade 5
3
*Main> getPointsFromGrade 6
2
*Main> getPointsFromGrade 7
1
*Main> getPointsFromGrade 8
0
*Main> getPointsFromGrade 9
-1
*Main> getPointsFromGrade (-10)
-1


Above application can be defined like below by using piece-wise definition.

pointsCals.hs
pointsforGrade 1 = 10
pointsforGrade 2 = 9
pointsforGrade 3 = 8
pointsforGrade 4 = 4
pointsforGrade 5 = 3
pointsforGrade 6 = 2
pointsforGrade 7 = 1
pointsforGrade 8 = 0
pointsforGrade _ = -1


‘_’ is a special wild card character, it matches with anything.
*Main> :load pointsCalc.hs
[1 of 1] Compiling Main             ( pointsCalc.hs, interpreted )
Ok, modules loaded: Main.
*Main> 
*Main> pointsforGrade 1
10
*Main> pointsforGrade 2
9
*Main> pointsforGrade 3
8
*Main> pointsforGrade 4
4
*Main> pointsforGrade 5
3
*Main> pointsforGrade 6
2
*Main> pointsforGrade 7
1
*Main> pointsforGrade 8
0
*Main> pointsforGrade 9
-1
*Main> pointsforGrade (-10)
-1
*Main> 


Always kept the ‘_’ character at end, if you kept the _ character at starting of your logic, it matches to all. For example, I updated pointsCalc.hs like below.

pointsCalc.hs
pointsforGrade _ = -1
pointsforGrade 1 = 10
pointsforGrade 2 = 9
pointsforGrade 3 = 8
pointsforGrade 4 = 4
pointsforGrade 5 = 3
pointsforGrade 6 = 2
pointsforGrade 7 = 1
pointsforGrade 8 = 0

*Main> :load pointsCalc.hs
[1 of 1] Compiling Main             ( pointsCalc.hs, interpreted )

pointsCalc.hs:1:1: Warning:
    Pattern match(es) are overlapped
    In an equation for pointsforGrade:
        pointsforGrade 1 = ...
        pointsforGrade 2 = ...
        pointsforGrade 3 = ...
        pointsforGrade 4 = ...
        ...
Ok, modules loaded: Main.
*Main> 
*Main> pointsforGrade 1
-1
*Main> pointsforGrade 2
-1
*Main> pointsforGrade 3
-1


Observe I am getting -1 for all the grades, it is because I kept ‘_’ symbol at starting of my logic, so it matches to all.

Mixing styles
You can re write the above program by mixing

pointsCalc.hs
pointsforGrade 1 = 10
pointsforGrade 2 = 9
pointsforGrade 3 = 8
pointsforGrade x 
    | (x > 3 && x < 9) = 8-x
    | otherwise = -1

*Main> :load pointsCalc.hs
[1 of 1] Compiling Main             ( pointsCalc.hs, interpreted )
Ok, modules loaded: Main.
*Main> 
*Main> pointsforGrade 1
10
*Main> pointsforGrade 2
9
*Main> pointsforGrade 3
8
*Main> pointsforGrade 4
4
*Main> pointsforGrade 5
3
*Main> pointsforGrade 6
2
*Main> pointsforGrade 7
1
*Main> pointsforGrade 8
0
*Main> pointsforGrade 8
0
*Main> pointsforGrade 9
-1
*Main> pointsforGrade (-10)
-1




Previous                                                 Next                                                 Home

No comments:

Post a Comment