Send Beginners mailing list submissions to
        [email protected]

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
        [email protected]

You can reach the person managing the list at
        [email protected]

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 <[email protected]>
To: The Haskell-Beginners Mailing List - Discussion of primarily
        beginner-level topics related to Haskell <[email protected]>
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 <[email protected]>
To: The Haskell-Beginners Mailing List - Discussion of primarily
        beginner-level topics related to Haskell <[email protected]>
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 <[email protected]> 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
> [email protected]
> 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 <[email protected]>
To: The Haskell-Beginners Mailing List - Discussion of primarily
        beginner-level topics related to Haskell <[email protected]>
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 <[email protected]>
To: The Haskell-Beginners Mailing List - Discussion of primarily
        beginner-level topics related to Haskell <[email protected]>
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 <[email protected]>
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 <[email protected]> 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
>> [email protected]
>> http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners
>>
>>
>
> _______________________________________________
> Beginners mailing list
> [email protected]
> 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 <[email protected]>
To: The Haskell-Beginners Mailing List - Discussion of primarily
        beginner-level topics related to Haskell <[email protected]>
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
[email protected]
http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners


------------------------------

End of Beginners Digest, Vol 88, Issue 17
*****************************************

Reply via email to