<div dir="ltr">Just like sequence, there is also a function sequence_ that you might want to use.<div><br></div><div><span style="font-family:monospace,monospace">    sequence_ :: Monad m => [m a] -> m ()</span><span style="font-family:monospace,monospace">    -- for m = IO, sequence_ :: [IO a] -> IO ()</span></div><div><span style="font-family:monospace,monospace">    sequence_ lst = do</span><br></div><div><font face="monospace, monospace">      sequence lst</font></div><div><font face="monospace, monospace">      return ()</font></div><div><br></div><div><font face="monospace, monospace">    -- also, mapM and mapM_ are useful too</font></div><div><font face="monospace, monospace">    mapM f  = sequence . map f      -- retains results</font></div><div><font face="monospace, monospace">    mapM_ f = sequence_ . map f     -- ignores results</font></div><div><font face="monospace, monospace"><br></font></div><div><font face="monospace, monospace">    -- Some use cases</font></div><div><font face="monospace, monospace">    ghci> sequence [print 2, print 3]</font></div><div><font face="monospace, monospace">      2</font></div><div><font face="monospace, monospace">      3</font></div><div><font face="monospace, monospace">      [(),()]      -- The results, each print is of type IO (), i.e does IO and produces ()</font></div><div><font face="monospace, monospace">    ghci> mapM print [2,3] -- same as above</font></div><div><font face="monospace, monospace">    ghci> mapM_ print [2,3] -- same as above, but without results (or result of type unit, i.e ())</font></div><div><br></div></div><div class="gmail_extra"><br><div class="gmail_quote">On 10 March 2015 at 02:09, Joel Williamson <span dir="ltr"><<a href="mailto:joel.s.williamson@gmail.com" target="_blank">joel.s.williamson@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">sequence will get the types to match up, but a more elegant solution<br>
would be to get every line into a single string, then print that.<br>
<br>
putStrLn $ unlines $ map show newList<br>
<br>
I agree that getting the types to line up can be a nuisance, and with<br>
such small programs it doesn't bring much of an advantage. Ultimately,<br>
if you want side-effects to be reflected in the type system, there<br>
will be times you have to do a bit of extra work to satisfy the type<br>
checker. Learning to write well-typed code is much easier in this<br>
context, where everything has a fairly concrete type and there is lots<br>
of documentation, than having to learn it later when you have weird<br>
types coming from 3 different libraries and are facing a problem no<br>
one else has had. I would recommend getting very comfortable with GHCi<br>
and Hoogle.<br>
<br>
If you haven't already, add a hoogle prompt to GHCi by pasting something like<br>
:def hoogle \str -> return $ ":! hoogle --count=15 \"" ++ str ++ "\""<br>
in your ghci.conf. This will allow you to easily search for functions<br>
of a given type. Typing<br>
:hoogle [IO a] -> IO [a]<br>
returned all the information needed to answer your question.<br>
<span class="im HOEnZb"><br>
<br>
On Mon, Mar 9, 2015 at 4:25 PM, Geoffrey Bays <<a href="mailto:charioteer7@gmail.com">charioteer7@gmail.com</a>> wrote:<br>
</span><div class="HOEnZb"><div class="h5">> Thanks, Joel.<br>
><br>
> Putting the type IO [()] in the main declaration and this as the final line<br>
> of the main function does do the trick:<br>
><br>
> sequence [putStrLn $ show s | s <- newList]<br>
><br>
> But this is the kind of thing that makes Haskell types difficult for<br>
> beginners to work with...<br>
><br>
> Geoffrey<br>
><br>
> On Mon, Mar 9, 2015 at 4:15 PM, Joel Williamson<br>
> <<a href="mailto:joel.s.williamson@gmail.com">joel.s.williamson@gmail.com</a>> wrote:<br>
>><br>
>> main must have type IO a. Hoogle tells me that to convert [IO a] -> IO<br>
>> [a], you should use the function sequence. Try applying that to your final<br>
>> line.<br>
>><br>
>><br>
>> On Mon, 9 Mar 2015 16:07 Geoffrey Bays <<a href="mailto:charioteer7@gmail.com">charioteer7@gmail.com</a>> wrote:<br>
>>><br>
>>> My main function looks like this:<br>
>>><br>
>>> main :: [IO()]<br>
>>> main = do<br>
>>>     let stud1 = Student {name = "Geoff", average = -99.0, grades =<br>
>>> [66,77,88]}<br>
>>>     let stud2 = Student {name = "Doug", average = -99.0, grades =<br>
>>> [77,88,99]}<br>
>>>     let stud3 = Student {name = "Ron", average = -99.0, grades =<br>
>>> [55,66,77]}<br>
>>>     let studList = [stud1,stud2]<br>
>>>     let newList = calcAvg studList<br>
>>>     [putStrLn $ show s | s <- newList]<br>
>>>     --putStrLn $ show (newList !! 0)<br>
>>>     --putStrLn $ show (newList !! 1)<br>
>>><br>
>>> With this final line, putStrLn $ show (newList !! 0), the type IO () in<br>
>>> the function declaration compiles fine.<br>
>>> But with [putStrLn $ show s | s <- newList] as the final line, [IO ()] in<br>
>>> the function declaration will not compile, I get this error:<br>
>>><br>
>>>     Couldn't match expected type `IO t0' with actual type `[IO ()]'<br>
>>><br>
>>> What does the declared type need to be for a final line of:<br>
>>> [putStrLn $ show s | s <- newList]  ???<br>
>>><br>
>>> Thanks,<br>
>>><br>
>>> Geoffrey<br>
>>><br>
>>> _______________________________________________<br>
>>> Beginners mailing list<br>
>>> <a href="mailto:Beginners@haskell.org">Beginners@haskell.org</a><br>
>>> <a href="http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners" target="_blank">http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners</a><br>
>><br>
>><br>
>> _______________________________________________<br>
>> Beginners mailing list<br>
>> <a href="mailto:Beginners@haskell.org">Beginners@haskell.org</a><br>
>> <a href="http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners" target="_blank">http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners</a><br>
>><br>
><br>
><br>
> _______________________________________________<br>
> Beginners mailing list<br>
> <a href="mailto:Beginners@haskell.org">Beginners@haskell.org</a><br>
> <a href="http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners" target="_blank">http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners</a><br>
><br>
_______________________________________________<br>
Beginners mailing list<br>
<a href="mailto:Beginners@haskell.org">Beginners@haskell.org</a><br>
<a href="http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners" target="_blank">http://mail.haskell.org/cgi-bin/mailman/listinfo/beginners</a><br>
</div></div></blockquote></div><br><br clear="all"><div><br></div>-- <br><div class="gmail_signature"><div dir="ltr"><div><div dir="ltr"><div dir="ltr"><div>Regards</div><div dir="ltr"><div><br></div><div>Sumit Sahrawat</div></div></div></div></div></div></div>
</div>