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. 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 <[email protected]>
To: [email protected]
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 <[email protected]>
To: [email protected]
Subject: Re: [Haskell-beginners] Use of interact
Message-ID: <[email protected]>
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 <[email protected]>
To: The Haskell-Beginners Mailing List - Discussion of primarily
beginner-level topics related to Haskell <[email protected]>
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 <[email protected]>
To: [email protected]
Subject: Re: [Haskell-beginners] Use of interact
Message-ID: <[email protected]>
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
[email protected]
http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners
------------------------------
End of Beginners Digest, Vol 128, Issue 4
*****************************************