Home > database >  return type of (fmap.fmap) func vs fmap (fmap func)
return type of (fmap.fmap) func vs fmap (fmap func)

Time:10-04

following is the sample code I am testing

import Control.Exception

safeLoad :: FilePath -> IO (Either IOException String)
safeLoad f = (Right <$> readFile f) `catch` (pure . Left)

fileChars :: FilePath -> IO (Either IOException Int)
fileChars = fmap (fmap length) . safeLoad

fileChars' :: FilePath -> IO Int
fileChars' = (fmap.fmap) length safeLoad

example :: [Maybe Integer]
example = (fmap.fmap) ( 1) [Just 2,Just 3]

here the type of (fmap.fmap) evaluates as:

ghci> :t ((fmap.fmap) length)
((fmap.fmap) length)
  :: (Functor f1, Functor f2, Foldable t) =>
     f1 (f2 (t a)) -> f1 (f2 Int)

the type of (fmap (fmap ...)) also is:

ghci> :t (fmap (fmap length))
(fmap (fmap length))
  :: (Functor f1, Functor f2, Foldable t) =>
     f1 (f2 (t a)) -> f1 (f2 Int)

but why does fileChars' return IO Int while fileChars return IO (Either IOException Int)?

CodePudding user response:

Because

fileChars' = (fmap.fmap) length safeLoad
           = fmap (fmap length) safeLoad

while

fileChars = fmap (fmap length) . safeLoad

Mind the dot. The two expressions are not equivalent.

  • Related