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.  Use of interact (Michele Alzetta)
   2. Re:  Use of interact (Francesco Ariis)
   3. Re:  Use of interact (Michele Alzetta)
   4. Re:  Use of interact (Francesco Ariis)


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

Message: 1
Date: Sun, 10 Feb 2019 17:10:13 +0100
From: Michele Alzetta <michele.alze...@gmail.com>
To: beginners@haskell.org
Subject: [Haskell-beginners] Use of interact
Message-ID:
        <canhs-xbzeg3uohognnnkbfb9jaay+km_tyhi+-be-4cbah+...@mail.gmail.com>
Content-Type: text/plain; charset="utf-8"

I solved the hacker-rank hello world n times challenge thus:

hello_worlds :: Int -> IO ()
hello_worlds n
| n < 1 = return ()
| otherwise = do
putStrLn "Hello World"
hello_worlds (n-1)

main :: IO()
main = do
n <- readLn :: IO Int
hello_worlds n

I would like to solve this by using the interact function.
If I leave my hello_worlds function as is and change the main function as
follows:

main = interact $ show . hello_worlds . read::Int

I get:

Couldn't match expected type ‘IO t0’ with actual type ‘Int’
    • In the expression: main
      When checking the type of the IO action ‘main’

helloworlds.hs:14:8-44: error:
    • Couldn't match expected type ‘Int’ with actual type ‘IO ()’
    • In the expression: interact $ show . hello_worlds . read :: Int
      In an equation for ‘main’:
          main = interact $ show . hello_worlds . read :: Int

could someone please explain why this can't work?
Is it possible to use interact in such a context?

Thanks
-------------- next part --------------
An HTML attachment was scrubbed...
URL: 
<http://mail.haskell.org/pipermail/beginners/attachments/20190210/21c11099/attachment-0001.html>

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

Message: 2
Date: Sun, 10 Feb 2019 17:39:09 +0100
From: Francesco Ariis <fa...@ariis.it>
To: beginners@haskell.org
Subject: Re: [Haskell-beginners] Use of interact
Message-ID: <20190210163909.3eaccd55uceq6...@x60s.casa>
Content-Type: text/plain; charset=utf-8

Ciao Michele,

On Sun, Feb 10, 2019 at 05:10:13PM +0100, Michele Alzetta wrote:
> If I leave my hello_worlds function as is and change the main function as
> follows:
> 
> main = interact $ show . hello_worlds . read::Int
> 
> I get: [...]
> 
> helloworlds.hs:14:8-44: error:
>     • Couldn't match expected type ‘Int’ with actual type ‘IO ()’
>     • In the expression: interact $ show . hello_worlds . read :: Int
>       In an equation for ‘main’:
>           main = interact $ show . hello_worlds . read :: Int

Two facts:

    - (.) is an operator which concatenates function
    - to concatenate functions, input/outputs must match

So let's analyse this:

    1. `read` has type `Read a => String -> a`
    2. `hello_worlds` has type `Int -> IO ()`
    3. `show` has type `Show a => a -> String`

and there is no way to convert `IO ()` to `String`. Remember that
hello_worlds does *not* return a series of Strings, but an IO action
(in this case, "blit something to screen")

Your `interact` example would function if written like this:

    main = interact $ unlines . map (hello_pure . read) . lines
    -- with `hello_pure :: Int -> String`

`lines` and `unlines` are there to keep input lazy for each line.
Do you think you can you fill-in "hello_pure" yourself?
-F


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

Message: 3
Date: Sun, 10 Feb 2019 21:59:54 +0100
From: Michele Alzetta <michele.alze...@gmail.com>
To: The Haskell-Beginners Mailing List - Discussion of primarily
        beginner-level topics related to Haskell <beginners@haskell.org>
Subject: Re: [Haskell-beginners] Use of interact
Message-ID:
        <canhs-xagne7h1qsbcnbjhtpa1azjtqr6mdk_d4wu+chm3is...@mail.gmail.com>
Content-Type: text/plain; charset="utf-8"

Francesco,

thanks, that was very enlightening.  That concatenated functions should
have matching inputs / outputs is obvious of course, but I just didn't
think of that. Duh!
That IO () can't be converted to String is probably just as obvious, but it
wasn't for me.

For hello_pure I tried this:

hello_pure :: Int -> String
hello_pure n
| n < 1 = ""
| otherwise = "Hello World" ++ "\n" ++ hello_pure ( n - 1 )

And it works, although
++ "\n" ++
doesn't feel so elegant.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: 
<http://mail.haskell.org/pipermail/beginners/attachments/20190210/af25c43b/attachment-0001.html>

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

Message: 4
Date: Sun, 10 Feb 2019 23:59:32 +0100
From: Francesco Ariis <fa...@ariis.it>
To: beginners@haskell.org
Subject: Re: [Haskell-beginners] Use of interact
Message-ID: <20190210225932.tr4yx7pldkvrp...@x60s.casa>
Content-Type: text/plain; charset=us-ascii

On Sun, Feb 10, 2019 at 09:59:54PM +0100, Michele Alzetta wrote:
> For hello_pure I tried this:
> 
> hello_pure :: Int -> String
> hello_pure n
> | n < 1 = ""
> | otherwise = "Hello World" ++ "\n" ++ hello_pure ( n - 1 )
> 

Very good!

> And it works, although
> ++ "\n" ++
> doesn't feel so elegant.

If you want, you can rewrite is as a one-liner like this:

    hp2 :: Int -> String
    hp2 n = unlines $ replicate n "Hello world"

-F


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

Subject: Digest Footer

_______________________________________________
Beginners mailing list
Beginners@haskell.org
http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners


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

End of Beginners Digest, Vol 128, Issue 4
*****************************************

Reply via email to