More direct binding of IO result

I understand that one can bind the unwrapped results of IO functions to variables, and pass them to functions, like so: main = do filecontents <- readFile "data.txt" putStrLn filecontents But does the syntax allow you to cut out the middle man, so to speak, and bind the results directly to the parameter? Like -- Tried this and it didn't work. main = do putStrLn (<- readFile "data.txt") -- frigidcode.com theologia.indicium.us

On Sun, May 15, 2011 at 9:27 AM, Christopher Howard < christopher.howard@frigidcode.com> wrote:
I understand that one can bind the unwrapped results of IO functions to variables, and pass them to functions, like so:
main = do filecontents <- readFile "data.txt" putStrLn filecontents
But does the syntax allow you to cut out the middle man, so to speak, and bind the results directly to the parameter? Like
-- Tried this and it didn't work. main = do putStrLn (<- readFile "data.txt")
do-notation is just syntactic sugar for the ">>" and ">>=" operators. Your example gets translated internally to:
readFile "data.txt" >>= \filecontents -> putStrLn filecontents To get rid of that extra "filecontents", you could instead write: readFile "data.txt" >>= putStrLn HTH, Michael

On Sunday 15 May 2011 08:29:10, Michael Snoyman wrote:
On Sun, May 15, 2011 at 9:27 AM, Christopher Howard <
christopher.howard@frigidcode.com> wrote:
I understand that one can bind the unwrapped results of IO functions to variables, and pass them to functions, like so:
main = do filecontents <- readFile "data.txt"
putStrLn filecontents
But does the syntax allow you to cut out the middle man, so to speak, and bind the results directly to the parameter? Like
-- Tried this and it didn't work. main = do putStrLn (<- readFile "data.txt")
do-notation is just syntactic sugar for the ">>" and ">>=" operators. Your
example gets translated internally to:
readFile "data.txt" >>= \filecontents -> putStrLn filecontents
To get rid of that extra "filecontents", you could instead write:
readFile "data.txt" >>= putStrLn
Or, if you prefer to read your data-flow right-to-left: putStrLn =<< readFile "data.txt"

-- Tried this and it didn't work. main = do putStrLn (<- readFile "data.txt")
My question; how come fmap doesn's also work here? (though it's not a syntax-based solution): Prelude> fmap putStrLn (readFile "data.txt") Prelude> I thought it may have operated to make a new IO action, but if that were the case then ghci should have executed the result here. A

On Sun, May 15, 2011 at 9:49 AM, Arlen Cuss
-- Tried this and it didn't work. main = do putStrLn (<- readFile "data.txt")
My question; how come fmap doesn's also work here? (though it's not a syntax-based solution):
Prelude> fmap putStrLn (readFile "data.txt") Prelude>
I thought it may have operated to make a new IO action, but if that were the case then ghci should have executed the result here.
Let's look at the types. Specializing to IO, readFile "data.txt" :: IO String fmap :: (a -> b) -> IO a -> IO b putStrLn :: String -> IO () fmap putStrLn :: IO String -> IO (IO ()) Notice how there are now *two* IOs in "fmap putStrLn". Therefore, the result of "fmap putStrLn (readFile "data.txt")" is of type "IO (IO ())". The way to get rid of that extra IO is via the join function, which has type (specialized for IO): join :: IO (IO a) -> IO a So you could write: import Control.Monad (join) main = join (fmap putStrLn (readFile "data.txt")) Michael

You can also try the applicative way: (<$>) :: (a -> b) -> f a -> f b import Control.Applicative -- Think of the <$> as a monadic version of $ main = putStrLn <$> readFile "contents.txt" Or if you want to chain the functions and not worry about the "contents.txt" argument: import Control.Monad main= (readFile >=> putStrLn) "contents.txt" -deech On Sun, May 15, 2011 at 1:27 AM, Christopher Howard < christopher.howard@frigidcode.com> wrote:
I understand that one can bind the unwrapped results of IO functions to variables, and pass them to functions, like so:
main = do filecontents <- readFile "data.txt" putStrLn filecontents
But does the syntax allow you to cut out the middle man, so to speak, and bind the results directly to the parameter? Like
-- Tried this and it didn't work. main = do putStrLn (<- readFile "data.txt")
-- frigidcode.com theologia.indicium.us
_______________________________________________ Beginners mailing list Beginners@haskell.org http://www.haskell.org/mailman/listinfo/beginners

You can also try the applicative way: (<$>) :: (a -> b) -> f a -> f b
import Control.Applicative -- Think of the <$> as a monadic version of $ main = putStrLn <$> readFile "contents.txt"
Actually, <$> is just a synonym for fmap, so this will have the same
On Sun, May 15, 2011 at 2:56 PM, aditya siram
Or if you want to chain the functions and not worry about the "contents.txt" argument:
import Control.Monad main= (readFile >=> putStrLn) "contents.txt"
-deech
On Sun, May 15, 2011 at 1:27 AM, Christopher Howard < christopher.howard@frigidcode.com> wrote:
I understand that one can bind the unwrapped results of IO functions to variables, and pass them to functions, like so:
main = do filecontents <- readFile "data.txt" putStrLn filecontents
But does the syntax allow you to cut out the middle man, so to speak, and bind the results directly to the parameter? Like
-- Tried this and it didn't work. main = do putStrLn (<- readFile "data.txt")
-- frigidcode.com theologia.indicium.us
_______________________________________________ Beginners mailing list Beginners@haskell.org http://www.haskell.org/mailman/listinfo/beginners
_______________________________________________ Beginners mailing list Beginners@haskell.org http://www.haskell.org/mailman/listinfo/beginners

Crap! You're right, should've tried it out. Sorry Christopher! The second
approach does work though.
-deech
On Sun, May 15, 2011 at 6:58 AM, Michael Snoyman
On Sun, May 15, 2011 at 2:56 PM, aditya siram
wrote: You can also try the applicative way: (<$>) :: (a -> b) -> f a -> f b
import Control.Applicative -- Think of the <$> as a monadic version of $ main = putStrLn <$> readFile "contents.txt"
Actually, <$> is just a synonym for fmap, so this will have the same problems as the fmap approach.
Michael
Or if you want to chain the functions and not worry about the "contents.txt" argument:
import Control.Monad main= (readFile >=> putStrLn) "contents.txt"
-deech
On Sun, May 15, 2011 at 1:27 AM, Christopher Howard < christopher.howard@frigidcode.com> wrote:
I understand that one can bind the unwrapped results of IO functions to variables, and pass them to functions, like so:
main = do filecontents <- readFile "data.txt" putStrLn filecontents
But does the syntax allow you to cut out the middle man, so to speak, and bind the results directly to the parameter? Like
-- Tried this and it didn't work. main = do putStrLn (<- readFile "data.txt")
-- frigidcode.com theologia.indicium.us
_______________________________________________ Beginners mailing list Beginners@haskell.org http://www.haskell.org/mailman/listinfo/beginners
_______________________________________________ Beginners mailing list Beginners@haskell.org http://www.haskell.org/mailman/listinfo/beginners
participants (5)
-
aditya siram
-
Arlen Cuss
-
Christopher Howard
-
Daniel Fischer
-
Michael Snoyman