Send Beginners mailing list submissions to beginners@haskell.org To subscribe or unsubscribe via the World Wide Web, visit http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners or, via email, send a message with subject or body 'help' to beginners-requ...@haskell.org
You can reach the person managing the list at beginners-ow...@haskell.org When replying, please edit your Subject line so it is more specific than "Re: Contents of Beginners digest..." Today's Topics: 1. Why can't I print an IO Integer? (Dan Stromberg) 2. Re: Why can't I print an IO Integer? (Petr V?penka) 3. Re: Why can't I print an IO Integer? (Marcin Mrotek) 4. Re: Why can't I print an IO Integer? (Dan Stromberg) 5. Re: Why can't I print an IO Integer? (Marcin Mrotek) ---------------------------------------------------------------------- Message: 1 Date: Tue, 20 Oct 2015 08:58:46 -0700 From: Dan Stromberg <strom...@gmail.com> To: The Haskell-Beginners Mailing List - Discussion of primarily beginner-level topics related to Haskell <beginners@haskell.org> Subject: [Haskell-beginners] Why can't I print an IO Integer? Message-ID: <caovkw542hgss66njnorquhobtzxg0lwz0qzq9ou30kuiu6w...@mail.gmail.com> Content-Type: text/plain; charset="utf-8" Here's a small program that replicates the compilation issue I'm seeing: import qualified System.Posix.Files get_size :: String -> IO Integer get_size filename = do file_status <- System.Posix.Files.getFileStatus filename let file_size = System.Posix.Files.fileSize file_status let integer_file_size = fromIntegral file_size return integer_file_size main :: IO () main = do let filenames = ["/etc/services"] let sizes = map get_size filenames mapM_ print sizes The compilation error I get is: ghc -Wall --make -o stat2 stat2.hs [1 of 1] Compiling Main ( stat2.hs, stat2.o ) stat2.hs:15:11: No instance for (Show (IO Integer)) arising from a use of `print' Possible fix: add an instance declaration for (Show (IO Integer)) In the first argument of `mapM_', namely `print' In a stmt of a 'do' block: mapM_ print sizes In the expression: do { let filenames = ...; let sizes = map get_size filenames; mapM_ print sizes } make: *** [stat2] Error 1 I've googled quite a bit, and guessed quite a bit, and added type declarations some, but I'm still not converging on a solution. Why can't I print an IO Integer? Thanks! -- Dan Stromberg -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://mail.haskell.org/pipermail/beginners/attachments/20151020/f1cdc810/attachment-0001.html> ------------------------------ Message: 2 Date: Tue, 20 Oct 2015 18:15:00 +0200 From: Petr V?penka <petr.vape...@gmail.com> To: The Haskell-Beginners Mailing List - Discussion of primarily beginner-level topics related to Haskell <beginners@haskell.org> Subject: Re: [Haskell-beginners] Why can't I print an IO Integer? Message-ID: <candmeuchkf1nsatj+ovanoqjkgjhnkr1sld5+tutpc0den1...@mail.gmail.com> Content-Type: text/plain; charset="utf-8" Hello Dan, `IO Integer` is something that, when executed, returns and `Integer` and there is no instance of `Show` for `IO Integer` as the compiler says. You have to run the computations that will return the numbers and then print them, like so: main :: IO () main = do let filenames = ["/etc/services"] let ioSizes = map get_size filenames :: [IO Integer] sizes <- sequence ioSizes mapM_ print sizes -- sequence :: Monad m => [m a] -> m [a] One important part is the use of sequence which transforms (ioSizes :: [IO Integer]) to `IO [Integer]` that is run and the result bound to (sizes : [Integer]). Hope that's clear enough to get the point :) Petr On Tue, Oct 20, 2015 at 5:58 PM, Dan Stromberg <strom...@gmail.com> wrote: > > Here's a small program that replicates the compilation issue I'm seeing: > > import qualified System.Posix.Files > > get_size :: String -> IO Integer > get_size filename = do > file_status <- System.Posix.Files.getFileStatus filename > let file_size = System.Posix.Files.fileSize file_status > let integer_file_size = fromIntegral file_size > return integer_file_size > > main :: IO () > main = do > let filenames = ["/etc/services"] > let sizes = map get_size filenames > mapM_ print sizes > > The compilation error I get is: > > ghc -Wall --make -o stat2 stat2.hs > [1 of 1] Compiling Main ( stat2.hs, stat2.o ) > > stat2.hs:15:11: > No instance for (Show (IO Integer)) arising from a use of `print' > Possible fix: add an instance declaration for (Show (IO Integer)) > In the first argument of `mapM_', namely `print' > In a stmt of a 'do' block: mapM_ print sizes > In the expression: > do { let filenames = ...; > let sizes = map get_size filenames; > mapM_ print sizes } > make: *** [stat2] Error 1 > > I've googled quite a bit, and guessed quite a bit, and added type > declarations some, but I'm still not converging on a solution. > > Why can't I print an IO Integer? > > Thanks! > > -- > Dan Stromberg > > _______________________________________________ > Beginners mailing list > Beginners@haskell.org > http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners > > -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://mail.haskell.org/pipermail/beginners/attachments/20151020/45f851db/attachment-0001.html> ------------------------------ Message: 3 Date: Tue, 20 Oct 2015 18:17:14 +0200 From: Marcin Mrotek <marcin.jan.mro...@gmail.com> To: The Haskell-Beginners Mailing List - Discussion of primarily beginner-level topics related to Haskell <beginners@haskell.org> Subject: Re: [Haskell-beginners] Why can't I print an IO Integer? Message-ID: <CAJcfPz=nbzrJb0LJFSUY8FuZjmiO_R=8wx6gvgkj0nm8tt8...@mail.gmail.com> Content-Type: text/plain; charset="utf-8" Hello, Function "print" has type "Show a => a -> IO ()". To use it with a value of type "IO Int", you need to use (>>=), which, specialized to IO, has type "IO a -> (a -> IO b) -> IO b". "print =<< foo", if foo :: IO Int, will have type IO () and is going to print the integer from foo. In your code, though, you can use mapM instead of map: sizes <- mapM get_size filenames mapM_ print sizes Best regards, Marcin Mrotek -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://mail.haskell.org/pipermail/beginners/attachments/20151020/f14ab47f/attachment-0001.html> ------------------------------ Message: 4 Date: Tue, 20 Oct 2015 12:28:30 -0700 From: Dan Stromberg <strom...@gmail.com> To: The Haskell-Beginners Mailing List - Discussion of primarily beginner-level topics related to Haskell <beginners@haskell.org> Subject: Re: [Haskell-beginners] Why can't I print an IO Integer? Message-ID: <caovkw54zcd_3jwda7uce7s-e9yxsayw7epupchbdvxddoxz...@mail.gmail.com> Content-Type: text/plain; charset="utf-8" Please correct my inference if I'm wrong: An IO Integer is not an integer, it's a promise to read an Integer later. The "sequence" function tells the runtime it's time to make good on that promise. Sound about right? Thanks! On Tue, Oct 20, 2015 at 9:15 AM, Petr V?penka <petr.vape...@gmail.com> wrote: > Hello Dan, > > `IO Integer` is something that, when executed, returns and `Integer` and > there is no instance of `Show` for `IO Integer` as the compiler says. > > You have to run the computations that will return the numbers and then > print them, like so: > > main :: IO () > main = do > let filenames = ["/etc/services"] > let ioSizes = map get_size filenames :: [IO Integer] > sizes <- sequence ioSizes > mapM_ print sizes > > -- sequence :: Monad m => [m a] -> m [a] > > One important part is the use of sequence which transforms (ioSizes :: [IO > Integer]) to `IO [Integer]` that is run and the result bound to (sizes : > [Integer]). > > Hope that's clear enough to get the point :) > > Petr > > On Tue, Oct 20, 2015 at 5:58 PM, Dan Stromberg <strom...@gmail.com> wrote: > >> >> Here's a small program that replicates the compilation issue I'm seeing: >> >> import qualified System.Posix.Files >> >> get_size :: String -> IO Integer >> get_size filename = do >> file_status <- System.Posix.Files.getFileStatus filename >> let file_size = System.Posix.Files.fileSize file_status >> let integer_file_size = fromIntegral file_size >> return integer_file_size >> >> main :: IO () >> main = do >> let filenames = ["/etc/services"] >> let sizes = map get_size filenames >> mapM_ print sizes >> >> The compilation error I get is: >> >> ghc -Wall --make -o stat2 stat2.hs >> [1 of 1] Compiling Main ( stat2.hs, stat2.o ) >> >> stat2.hs:15:11: >> No instance for (Show (IO Integer)) arising from a use of `print' >> Possible fix: add an instance declaration for (Show (IO Integer)) >> In the first argument of `mapM_', namely `print' >> In a stmt of a 'do' block: mapM_ print sizes >> In the expression: >> do { let filenames = ...; >> let sizes = map get_size filenames; >> mapM_ print sizes } >> make: *** [stat2] Error 1 >> >> I've googled quite a bit, and guessed quite a bit, and added type >> declarations some, but I'm still not converging on a solution. >> >> Why can't I print an IO Integer? >> >> Thanks! >> >> -- >> Dan Stromberg >> >> _______________________________________________ >> Beginners mailing list >> Beginners@haskell.org >> http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners >> >> > > _______________________________________________ > Beginners mailing list > Beginners@haskell.org > http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners > > -- Dan Stromberg -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://mail.haskell.org/pipermail/beginners/attachments/20151020/eea7e560/attachment-0001.html> ------------------------------ Message: 5 Date: Tue, 20 Oct 2015 21:36:30 +0200 From: Marcin Mrotek <marcin.jan.mro...@gmail.com> To: The Haskell-Beginners Mailing List - Discussion of primarily beginner-level topics related to Haskell <beginners@haskell.org> Subject: Re: [Haskell-beginners] Why can't I print an IO Integer? Message-ID: <CAJcfPz=HgSA43aTNoMVrWcPnxJK9KAT=cenmz9apdyo-dnu...@mail.gmail.com> Content-Type: text/plain; charset=UTF-8 > An IO Integer is not an integer, it's a promise to read an Integer later. > The "sequence" function tells the runtime it's time to make good on that > promise. Not exactly. You don't need "sequence" for a plain (IO Int), only for a list of IO actions. "sequence" just changes a "list of promises" into a "promise of a list": sequence :: (Traversable t, Monad m) => t (m a) -> m (t a) When specialized to IO and a list, the function becomes: sequence :: [IO a] -> IO [a] Also, for any f: sequence . map f === mapM f It is when you bind its result to your "main" (with "do" notation or (>>) and (>>=) operators) when it can interact with the rest of your program. You can bind it more than once, and it will be executed more than one time, like any other "IO something". Best regards, Marcin Mrotek ------------------------------ Subject: Digest Footer _______________________________________________ Beginners mailing list Beginners@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners ------------------------------ End of Beginners Digest, Vol 88, Issue 17 *****************************************