Friday, 29 April 2016

Haskell: $ operator: Avoid parentheses

The $ operator is used to avoid parentheses. Anything appearing after it will take precedence over anything that comes before.


Sample.hs
{-# LANGUAGE BangPatterns #-}

myMap :: (Integer -> Integer) -> [Integer] -> [Integer]
myMap fun [] = []
myMap fun (x:xs) = (fun x) : myMap fun xs

-- Double an element
doubleMe :: Integer -> Integer
doubleMe x = x*x

-- Return sum of elements of a list
addition :: [Integer] -> Integer
addition xs = addition' xs 0

addition' :: [Integer] -> Integer -> Integer
addition' [] !result= result
addition' (x:xs) !result = addition' (xs) (result+x)

Suppose, you want to calculate the sum of all elments of a list, after doubling every element. You may call ‘addition myMap doubleMe [1, 2, 3, 4]’.

addition myMap doubleMe [1, 2, 3, 4]

Problem with above statement is, since function takes precedence over all other things in Haskell, addition takes myMap as argument, which is not acceptable, so you will get following error.
*Main> addition myMap doubleMe [1, 2, 3, 4]

<interactive>:11:1:
    Couldn't match expected type (Integer -> Integer)
                                  -> [Integer] -> t
                with actual type Integer
    Relevant bindings include it :: t (bound at <interactive>:11:1)
    The function addition is applied to three arguments,
    but its type [Integer] -> Integer has only one
    In the expression: addition myMap doubleMe [1, 2, 3, 4]
    In an equation for it:
        it = addition myMap doubleMe [1, 2, 3, ....]

<interactive>:11:10:
    Couldn't match expected type [Integer]
                with actual type (Integer -> Integer) -> [Integer] -> [Integer]
    Probable cause: myMap is applied to too few arguments
    In the first argument of addition, namely myMap
    In the expression: addition myMap doubleMe [1, 2, 3, 4]


One way to solve above problem is by using paranthesis.
*Main> addition (myMap doubleMe [1, 2, 3, 4])
30

You can rewrite the same thing is ‘$’ operator like below.
*Main> addition $ myMap doubleMe [1, 2, 3, 4]
30

Haskell gives low precedence to the '$' operator, so both sides of '$' operator will be evaluated before function 'addition' is applied to 'myMap doubleMe [1, 2, 3, 4]'.




Previous                                                 Next                                                 Home

No comments:

Post a Comment