Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

fmap versus <$>

Tags:

haskell

According to the documentation <$> is an synonym for fmap and they have the following types:

(<$>) :: Functor f => (a -> b) -> f a -> f b
fmap :: Functor f => (a -> b) -> f a -> f b

So it seems to me, from the signatures above, that they take the arguments in the same order, the only difference being that one is infix and the other is not. I have two pieces of code, one using fmap, and the other using <$>. Why is it that only the former runs correctly?

import Control.Applicative
main :: IO ()
main = do
  [x, y] <- map read . words <$> getLine
  putStrLn $ show (x + y)

This one won't compile:

import Control.Applicative
main :: IO ()
main = do
  [x, y] <- map read . fmap words getLine
  putStrLn $ show (x + y)
like image 991
plx Avatar asked Oct 28 '25 12:10

plx


2 Answers

Precedence of operators is expressed as an integer between 0 and 9, while function application effectively has precedence 10 (higher than any operator).

(.) has very high precedence (9), while (<$>) has lower precedence (4), resulting in your first expression being parsed as

((map read) . words) <$> getLine

while your second expression is parsed as

(map read) . (fmap words getLine) 

resulting in an attempt to compose an IO [String] value with a function of type [String] -> [a].

like image 151
chepner Avatar answered Oct 30 '25 07:10

chepner


This is due to operator precedence. If we look at the source code, we see that:

infixl 4 <$>
infixr 9  .

So that means that if you write:

  map read . words  <$> getLine

Haskell sees this as:

(map read . words) <$> getLine

But if you write:

 map read  .  fmap words getLine 

Haskell sees this as:

(map read) . (fmap words getLine)

So the arguments of fmap are different.

If we however add brackets, the two will be equivalent:

import Control.Applicative

main :: IO ()
main = do
  [x, y] <- map read . (words <$> getLine)
  putStrLn $ show (x + y)
like image 41
Willem Van Onsem Avatar answered Oct 30 '25 09:10

Willem Van Onsem



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!