[Haskell-cafe] Data.List / Map: simple serialization?
Daniel Fischer
daniel.is.fischer at googlemail.com
Fri Jun 10 14:49:57 CEST 2011
On Friday 10 June 2011, 14:25:59, Dmitri O.Kondratiev wrote:
> Two questions:
> 1) Why to use 'fmap' at all if a complete file is read in a single line
> of text?
Well, it's a matter of taste whether to write
foo <- fmap read (readFile "bar")
stuffWithFoo
or
text <- readFile "bar"
let foo = read text
stuffWithFoo
The former saves one line of code (big deal).
>
> 2) Trying to use 'fmap' illustrates 1) producing an error (see below):
> main = do
> let xss = [[1,2,3],[4,5,6],[7,8],[9]]
> writeFile "output.txt" (show xss)
> xss2 <- fmap read (readFile "output.txt") :: [[Int]]
That type signature doesn't refer to xss2, but to the action to the right
of the "<-", `fmap read (readFile "output.txt")'
readFile "output.txt" :: IO String
so
fmap foo (readFile "output.txt") :: IO bar
supposing
foo :: String -> bar
You want read at the type `String -> [[Int]]', so the signature has to be
xss2 <- fmap read (readFile "output.txt") :: IO [[Int]]
> print xss2
>
> == Error:
> Couldn't match expected type `[String]'
> with actual type `IO String'
> In the return type of a call of `readFile'
> In the second argument of `fmap', namely `(readFile "output.txt")'
> In a stmt of a 'do' expression:
> xss2 <- fmap read (readFile "output.txt") :: [[Int]]
Looking at the line
xss2 <- fmap read someStuff :: [[Int]]
the compiler sees that
fmap read someStuff should have type [[Int]]
Now, fmap :: Functor f => (a -> b) -> f a -> f b
and [] is a Functor, so the fmap here is map, hence
map read someStuff :: [[Int]]
means
someStuff :: [String]
That's the expected type of (readFile "output.txt"), but the actual type is
of course IO String, which is the reported error.
More information about the Haskell-Cafe
mailing list