Use of interact

Next Topic
 
classic Classic list List threaded Threaded
4 messages Options
Reply | Threaded
Open this post in threaded view
|

Use of interact

Michele Alzetta
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


_______________________________________________
Beginners mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners
Reply | Threaded
Open this post in threaded view
|

Re: Use of interact

Francesco Ariis
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
_______________________________________________
Beginners mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners
Reply | Threaded
Open this post in threaded view
|

Re: Use of interact

Michele Alzetta
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.

_______________________________________________
Beginners mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners
Reply | Threaded
Open this post in threaded view
|

Re: Use of interact

Francesco Ariis
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
_______________________________________________
Beginners mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners