
2008/12/7 John Ky
Thanks for the clarification.
They're all the same, as you've explained:
Prelude> putStrLn $ (show . read) "123" *** Exception: Prelude.read: no parse
Prelude> putStrLn $ show $ read "123" *** Exception: Prelude.read: no parse
Prelude> putStrLn $ (\x -> show (read x)) "123" *** Exception: Prelude.read: no parse
Luke explained why the Exception is raised, I'll try to explain why this kind of problem happens in general: First two ways that work: Prelude> putStrLn $ (show :: Int -> String) . read $ "123" 123 Prelude> putStrLn $ show . (read :: String -> Int) $ "123" 123 In these examples we explicitly typed either the polymorphic producer (i.e. read) or the producer (i.e. show) so ghci can unify the type variables and figure out what is the right instance of the type class. Generally this happen wherever the type class member has a type variable only to the right of the type (either foo :: a or foo :: Something ->a). This kind of member is polymorphic on the result so the caller must define what it's expecting. "show . read" is saying to ghc both the result of read will define the type and the argument of show will define the type, which is a (kind of) mutually recursive typing issue.
-John
Best regards, Daniel Yokomizo