function not working as expected, type issues

K, so I have a function that I’m writing that takes a *string* and a *count* and prints the *string* to STDOUT *count* times: displayD :: IO () -> String -> Int displayD string count = do (count > 0) && hPutStr stdout string (count > 0) && displayD string (count - 1) However, when I try to compile the file, I get several errors; here’s a pastebin: http://pastebin.com/DEsuAvfz What I’m trying to do here is check to see if *count* is greater than 0, and then if it is, then I’d like to print *string* to STDOUT until *count* equals 0. I tried doing it via pattern matching, like so: displayD string (count > 0) = do But I haven’t seen any examples of how to do pattern matching in functions using *do*, that is *IO*, so I’m unsure if the above is even anywhere near correct. Still very uncomfortable with declaring function types: I have a hard time figuring out which type is returned and what type is expected as an arg. My initial guess is that the *first* type specified is the one returned, but I’m not sure. -- Alexej Magura Sent with Airmail

Try using guards:
displayD :: IO () -> String -> Int
displayD string count =
| count > 0 = hPutStr stdout string
| otherwise = displayD string (count - 1)
Alternatively use if, then, else.
On Wed, Apr 9, 2014 at 2:03 AM, Alexej Magura
K, so I have a function that I'm writing that takes a *string* and a *count* and prints the *string* to STDOUT *count* times:
displayD :: IO () -> String -> Int displayD string count = do (count > 0) && hPutStr stdout string (count > 0) && displayD string (count - 1)
However, when I try to compile the file, I get several errors; here's a pastebin: http://pastebin.com/DEsuAvfz
What I'm trying to do here is check to see if *count* is greater than 0, and then if it is, then I'd like to print *string* to STDOUT until *count* equals 0. I tried doing it via pattern matching, like so:
displayD string (count > 0) = do
But I haven't seen any examples of how to do pattern matching in functions using *do*, that is *IO*, so I'm unsure if the above is even anywhere near correct.
Still very uncomfortable with declaring function types: I have a hard time figuring out which type is returned and what type is expected as an arg. My initial guess is that the *first* type specified is the one returned, but I'm not sure.
-- Alexej Magura Sent with Airmail _______________________________________________ Beginners mailing list Beginners@haskell.org http://www.haskell.org/mailman/listinfo/beginners

I didn't look closely enough at what you wrote, you had several issues.
Let me try again:
displayD :: String -> Int -> IO ()
displayD string 0 = return ()
displayD string count = do
hPutStr stdout string
displayD string (count - 1)
This is one way to do it. You use the arguments themselves. Obviously
this won't work with negative counts.
displayD :: String -> Int -> IO ()
displayD string count
| count <= 0 = return ()
| otherwise = do
hPutStr stdout string
displayD string (count - 1)
And as for figuring out types. You should try to load your source file in
ghci, and then use the :t and :i commands liberally to inspect functions
you are using. You will begin to get the hang of it in no time.
On Wed, Apr 9, 2014 at 2:08 AM, David McBride
Try using guards:
displayD :: IO () -> String -> Int displayD string count = | count > 0 = hPutStr stdout string | otherwise = displayD string (count - 1)
Alternatively use if, then, else.
On Wed, Apr 9, 2014 at 2:03 AM, Alexej Magura
wrote: K, so I have a function that I'm writing that takes a *string* and a *count* and prints the *string* to STDOUT *count* times:
displayD :: IO () -> String -> Int displayD string count = do (count > 0) && hPutStr stdout string (count > 0) && displayD string (count - 1)
However, when I try to compile the file, I get several errors; here's a pastebin: http://pastebin.com/DEsuAvfz
What I'm trying to do here is check to see if *count* is greater than 0, and then if it is, then I'd like to print *string* to STDOUT until *count* equals 0. I tried doing it via pattern matching, like so:
displayD string (count > 0) = do
But I haven't seen any examples of how to do pattern matching in functions using *do*, that is *IO*, so I'm unsure if the above is even anywhere near correct.
Still very uncomfortable with declaring function types: I have a hard time figuring out which type is returned and what type is expected as an arg. My initial guess is that the *first* type specified is the one returned, but I'm not sure.
-- Alexej Magura Sent with Airmail _______________________________________________ Beginners mailing list Beginners@haskell.org http://www.haskell.org/mailman/listinfo/beginners

Hello Alexej
Il 09/apr/2014 08:03 "Alexej Magura"
K, so I have a function that I’m writing that takes a *string* and a
*count* and prints the *string* to STDOUT *count* times:
displayD :: IO () -> String -> Int displayD string count = do (count > 0) && hPutStr stdout string (count > 0) && displayD string (count - 1)
At glance at least one of your errors comes from your type signature being incorrect. Your function should takes first a String then an Int and should return an IO () because you're printing stuff. So: displayD :: IO () -> String -> Int should become: displayD :: String -> Int -> IO () Regards, Nadir

On April 9, 2014 9:03:54 AM GMT+03:00, Alexej Magura
K, so I have a function that I’m writing that takes a *string* and a *count* and prints the *string* to STDOUT *count* times:
displayD :: IO () -> String -> Int displayD string count = do (count > 0) && hPutStr stdout string (count > 0) && displayD string (count - 1)
However, when I try to compile the file, I get several errors; here’s a pastebin: http://pastebin.com/DEsuAvfz
The errors you see here are caused by GHC trying to make sense of what you wrote and failing. This is because the code you wrote isn't well-typed - that is, you're using values of types differing from the types GHC is expecting you to use. More on this below.
What I’m trying to do here is check to see if *count* is greater than 0, and then if it is, then I’d like to print *string* to STDOUT until *count* equals 0. I tried doing it via pattern matching, like so:
Thank you for explaining the problem you're trying to solve instead of Gesh problem you're facing. Most people don't have the decency to do that, leading to hours of pointless discussion. [0]
displayD string (count > 0) = do
But I haven’t seen any examples of how to do pattern matching in functions using *do*, that is *IO*, so I’m unsure if the above is even anywhere near correct.
do-blocks are no different from any other expression in Haskell when it comes to pattern-matching. I'd suggest starting out with a pure (no IO) version of your code, loading it into GHCi and playing around with it, then adding the IO once you feel comfortable with writing pure code. In general, it's considered good practice to separate impure code from pure code. In this case, that would mean creating a function returning the n-time self a concatenation of a string, then printing the result of that function elsewhere.
Still very uncomfortable with declaring function types: I have a hard time figuring out which type is returned and what type is expected as an arg. My initial guess is that the *first* type specified is the one returned, but I’m not sure.
I'm curious as to why you thought that. The directionality of the arrows in a type signature is quite clear, at least to me. a -> b is the type of functions *from* a *to* b. This is important to understand, especially once you start treading into higher-order-function-land, using functions such as map :: (a -> b) -> [a] -> [b] (can you guess what it does and how it does it? Can you do that just by looking at the type?). One further note. The errors you saw in your output were caused by this misunderstanding of function types, as well as a misunderstanding of the types do-blocks expect. From your coding style, it appears that you think of && in the way Bash does - as the function:
p && x = if p then x else *nothing* For some suitable *nothing*. However, this is not the case. Firstly, && is just a function that takes two values of type Book and returns True if both of them are True. Second, a function such as the one I described above exists for Monads, by the name of guard. But until you grasp pure Haskell, there is no point in confusing yourself with them yet. Anyway, all of the above means that passing a non-Bool value to && is not acceptable, and since hPutStr stdout string is not a value of type Bool, GHC complains. So, in brief, follow the arrows, values are not automatically cast as in other languages, && is not the guard operator from Bash, and get away from IO for your first couple of attempts with Haskell. Hoping to help, Gesh [0] - http://xyproblem.info/ Alexej, You have several things going on here.

On 4/9/2014 3:45 AM, Gesh wrote:
Thank you for explaining the problem you're trying to solve instead of Gesh problem you're facing.
Is that some jargon I'm missing? Hmm, I see that's your name and email address too.

On Sun, Apr 13, 2014 at 12:02 AM, John M. Dlugosz
On 4/9/2014 3:45 AM, Gesh wrote:
Thank you for explaining the problem you're trying to solve instead of Gesh problem you're facing.
Is that some jargon I'm missing? Hmm, I see that's your name and email address too.
I think it's just different mailers misinterpreting and badly wrapping different quoting styles. -- brandon s allbery kf8nh sine nomine associates allbery.b@gmail.com ballbery@sinenomine.net unix, openafs, kerberos, infrastructure, xmonad http://sinenomine.net

On April 13, 2014 7:02:19 AM GMT+03:00, "John M. Dlugosz"
On 4/9/2014 3:45 AM, Gesh wrote:
Thank you for explaining the problem you're trying to solve instead of Gesh problem you're facing.
Is that some jargon I'm missing? Hmm, I see that's your name and email address too.
_______________________________________________ Beginners mailing list Beginners@haskell.org http://www.haskell.org/mailman/listinfo/beginners
Sorry, my autocorrect must have put that in instead of "the". And it's the nickname I use, not jargon. Sorry.

an arg. My initial guess is that the *first* type specified is the one returned, but I’m not sure. I'm curious as to why you thought that. The directionality of the arrows in a type signature is quite clear, at least to me. a -> b is the type of functions *from* a *to* b. Well, most of the languages that I’ve used are dynamically typed, but the one language that I’m _kinda_ familiar with that _is_ statically typed is C: several of the Haskell tutorials that I’ve been reading describe that:
A :: Int means that *A* is _of_ type *Int*, which kind of sounds like A returns type Int functions such as map :: (a -> b) -> [a] -> [b] (can you guess what it does and how it does it? Can you do that just by looking at the type?). Map appears to take a lambda function, which takes type *a* returning type *b* (both of which are purely arbitrary), a list of type *a*, and returns a list of type *b*, applying the lambda function to each element in the list of type *a*. From your coding style, it appears that you think of && in the way Bash does - as the function:
p && x = if p then x else *nothing*
Something like that. Anyway, all of the above means that passing a non-Bool value to && is not acceptable, and since hPutStr stdout string is not a value of type Bool, GHC complains. Makes sense. -- Alexej Magura Sent with Airmail
participants (6)
-
Alexej Magura
-
Brandon Allbery
-
David McBride
-
Gesh
-
John M. Dlugosz
-
Nadir Sampaoli