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