Date Sorting Round Three

Garner, Robin Robin.Garner@crsrehab.gov.au
Fri, 15 Mar 2002 13:00:28 +1100


This message is in MIME format. Since your mail reader does not understand
this format, some or all of this message may not be legible.

------_=_NextPart_001_01C1CBC5.2DD9D150
Content-Type: text/plain;
	charset="iso-8859-1"

The problem you are trying to come to grips with here is one of the
watersheds in the learning curve that most people learning Haskell
encounter, namely how to use values returned in Monads.  I could point out
that you have already solved the same problem when you used getLine.

The question you need to ask yourself is not, "how do I convert a value of
type IO String to a value of type String", but "how do I use the result of a
calculation within the IO Monad".  Look at where you've already solved the
problem, and the answer will appear almost immediately.

Robin

-----Original Message-----
From: Michael Ruth [mailto:meruth@hotmail.com]
Sent: Friday, 15 March 2002 11:30
To: haskell-cafe@haskell.org
Subject: Date Sorting Round Three




long set of code here, I think I figured out what you all were telling me. 
Compose small functions then compose bigger functions from smaller
functions and so on...

The problem I am having is I have an (IO String) where I need a (String) and

it reports it as such:

ERROR "C:\Documents and Settings\drunkenmike\My 
Documents\Programming\Csci4501\H
askell\datesort.hs":41 - Type error in application
*** Expression     : separateIntoLines (getInput x)
*** Term           : getInput x
*** Type           : IO String
*** Does not match : [Char]

I am gonna mark line 41 with a * at the beginning of the line. I have been 
looking high and low for the answer to IOString -> String.... all I think I 
need to do (I think anyways)

By the way, thanks to everyone for their help.

import IO



---
-- Control Flow
---

datesort :: IO()
datesort = do {
putStr   "Enter a filename: ";
theFile <- getLine;
sortAndOutput (readInAndGetReady theFile);
}


--
-- Composite functions
--	1) Read in & Get ready to sort
--	2) sort & output
--
--

readInAndGetReady :: String -> [String]
*readInAndGetReady x =
   fixDates (makeSortableDates (linesToDates (separateIntoLines (getInput 
x))))

sortAndOutput :: [String] -> IO()
sortAndOutput x =
   writeTheFile (getOutput (makePrintableDates (qsort x)))




--
-- Make the date printable. Printable means a string consisting of
-- dates in the form dd mm yyyy (more or less undoes the make sortable f x)
--

makePrintableDates :: [String] -> [String]
makePrintableDates x = map makePrintableDate x

--
-- Make the date printable. Printable means a string consisting of
-- dates in the form dd mm yyyy (more or less undoes the make sortable f x)
--

makePrintableDate :: String -> String
makePrintableDate x = unwords (reverse (words x))

--
-- Make all the dates sortable. Sortable means a string consisting of
-- dates in the form yyyy mm dd
--

makeSortableDates :: [[String]] -> [String]
makeSortableDates x = map makeSortableDate x

--
-- Make the date sortable. Sortable means a string consisting of
-- dates in the form yyyy mm dd
--

makeSortableDate :: [String] -> String
makeSortableDate x = unwords (reverse x)

--
-- Get the input from the given file
--

getInput :: String -> IO String
getInput myfile
  = readFile myfile

--
-- Seperate the input file into an list of Strings
--

separateIntoLines :: String -> [String]
separateIntoLines str = lines str

--
-- Transform all the lines into dates
--

linesToDates :: [String] -> [[String]]
linesToDates x = map lineToDate x

--
-- Transform the lines into dates
--

lineToDate :: String -> [String]
lineToDate x = words x


--
-- Transform the dates into lines
--

getOutput :: [String] -> String
getOutput x = unlines x

--
-- Fix all the dates so that they are in the form 0x if x < 10
--

fixDates:: [String] -> [String]
fixDates x = map fixPrefixes x

--
-- Fix the dates so that they are in the form 0x if x < 10
--

fixPrefixes :: String -> String
fixPrefixes p
   | p == "1" 	= "01"
   | p == "2"	= "02"
   | p == "3" 	= "03"
   | p == "4"	= "04"
   | p == "5" 	= "05"
   | p == "6"	= "06"
   | p == "7" 	= "07"
   | p == "8"	= "08"
   | p == "9" 	= "09"
   | otherwise	= p

--
-- Quicksort the List of strings
--

qsort :: [String] -> [String]
qsort []     = []
qsort (x:xs) = qsort elts_lt_x ++ [x] ++ qsort elts_greq_x
		 where
		   elts_lt_x   = [y | y <- xs, y < x]
		   elts_greq_x = [y | y <- xs, y >= x]

--
-- Write the ouput string to a file
--

writeTheFile :: String -> IO()
writeTheFile x = writeFile "output.txt" x







_________________________________________________________________
Chat with friends online, try MSN Messenger: http://messenger.msn.com

_______________________________________________
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe

------_=_NextPart_001_01C1CBC5.2DD9D150
Content-Type: text/html;
	charset="iso-8859-1"
Content-Transfer-Encoding: quoted-printable

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN">
<HTML>
<HEAD>
<META HTTP-EQUIV=3D"Content-Type" CONTENT=3D"text/html; =
charset=3Diso-8859-1">
<META NAME=3D"Generator" CONTENT=3D"MS Exchange Server version =
5.5.2653.12">
<TITLE>RE: Date Sorting Round Three</TITLE>
</HEAD>
<BODY>

<P><FONT SIZE=3D2>The problem you are trying to come to grips with here =
is one of the watersheds in the learning curve that most people =
learning Haskell encounter, namely how to use values returned in =
Monads.&nbsp; I could point out that you have already solved the same =
problem when you used getLine.</FONT></P>

<P><FONT SIZE=3D2>The question you need to ask yourself is not, =
&quot;how do I convert a value of type IO String to a value of type =
String&quot;, but &quot;how do I use the result of a calculation within =
the IO Monad&quot;.&nbsp; Look at where you've already solved the =
problem, and the answer will appear almost immediately.</FONT></P>

<P><FONT SIZE=3D2>Robin</FONT>
</P>

<P><FONT SIZE=3D2>-----Original Message-----</FONT>
<BR><FONT SIZE=3D2>From: Michael Ruth [<A =
HREF=3D"mailto:meruth@hotmail.com">mailto:meruth@hotmail.com</A>]</FONT>=

<BR><FONT SIZE=3D2>Sent: Friday, 15 March 2002 11:30</FONT>
<BR><FONT SIZE=3D2>To: haskell-cafe@haskell.org</FONT>
<BR><FONT SIZE=3D2>Subject: Date Sorting Round Three</FONT>
</P>
<BR>
<BR>
<BR>

<P><FONT SIZE=3D2>long set of code here, I think I figured out what you =
all were telling me. </FONT>
<BR><FONT SIZE=3D2>Compose small functions then compose bigger =
functions from smaller</FONT>
<BR><FONT SIZE=3D2>functions and so on...</FONT>
</P>

<P><FONT SIZE=3D2>The problem I am having is I have an (IO String) =
where I need a (String) and </FONT>
<BR><FONT SIZE=3D2>it reports it as such:</FONT>
</P>

<P><FONT SIZE=3D2>ERROR &quot;C:\Documents and Settings\drunkenmike\My =
</FONT>
<BR><FONT SIZE=3D2>Documents\Programming\Csci4501\H</FONT>
<BR><FONT SIZE=3D2>askell\datesort.hs&quot;:41 - Type error in =
application</FONT>
<BR><FONT SIZE=3D2>*** Expression&nbsp;&nbsp;&nbsp;&nbsp; : =
separateIntoLines (getInput x)</FONT>
<BR><FONT SIZE=3D2>*** =
Term&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; : =
getInput x</FONT>
<BR><FONT SIZE=3D2>*** =
Type&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; : IO =
String</FONT>
<BR><FONT SIZE=3D2>*** Does not match : [Char]</FONT>
</P>

<P><FONT SIZE=3D2>I am gonna mark line 41 with a * at the beginning of =
the line. I have been </FONT>
<BR><FONT SIZE=3D2>looking high and low for the answer to IOString =
-&gt; String.... all I think I </FONT>
<BR><FONT SIZE=3D2>need to do (I think anyways)</FONT>
</P>

<P><FONT SIZE=3D2>By the way, thanks to everyone for their help.</FONT>
</P>

<P><FONT SIZE=3D2>import IO</FONT>
</P>
<BR>
<BR>

<P><FONT SIZE=3D2>---</FONT>
<BR><FONT SIZE=3D2>-- Control Flow</FONT>
<BR><FONT SIZE=3D2>---</FONT>
</P>

<P><FONT SIZE=3D2>datesort :: IO()</FONT>
<BR><FONT SIZE=3D2>datesort =3D do {</FONT>
<BR><FONT SIZE=3D2>putStr&nbsp;&nbsp; &quot;Enter a filename: =
&quot;;</FONT>
<BR><FONT SIZE=3D2>theFile &lt;- getLine;</FONT>
<BR><FONT SIZE=3D2>sortAndOutput (readInAndGetReady theFile);</FONT>
<BR><FONT SIZE=3D2>}</FONT>
</P>
<BR>

<P><FONT SIZE=3D2>--</FONT>
<BR><FONT SIZE=3D2>-- Composite functions</FONT>
<BR><FONT SIZE=3D2>--&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1) Read in &amp; =
Get ready to sort</FONT>
<BR><FONT SIZE=3D2>--&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2) sort &amp; =
output</FONT>
<BR><FONT SIZE=3D2>--</FONT>
<BR><FONT SIZE=3D2>--</FONT>
</P>

<P><FONT SIZE=3D2>readInAndGetReady :: String -&gt; [String]</FONT>
<BR><FONT SIZE=3D2>*readInAndGetReady x =3D</FONT>
<BR><FONT SIZE=3D2>&nbsp;&nbsp; fixDates (makeSortableDates =
(linesToDates (separateIntoLines (getInput </FONT>
<BR><FONT SIZE=3D2>x))))</FONT>
</P>

<P><FONT SIZE=3D2>sortAndOutput :: [String] -&gt; IO()</FONT>
<BR><FONT SIZE=3D2>sortAndOutput x =3D</FONT>
<BR><FONT SIZE=3D2>&nbsp;&nbsp; writeTheFile (getOutput =
(makePrintableDates (qsort x)))</FONT>
</P>
<BR>
<BR>
<BR>

<P><FONT SIZE=3D2>--</FONT>
<BR><FONT SIZE=3D2>-- Make the date printable. Printable means a string =
consisting of</FONT>
<BR><FONT SIZE=3D2>-- dates in the form dd mm yyyy (more or less undoes =
the make sortable f x)</FONT>
<BR><FONT SIZE=3D2>--</FONT>
</P>

<P><FONT SIZE=3D2>makePrintableDates :: [String] -&gt; [String]</FONT>
<BR><FONT SIZE=3D2>makePrintableDates x =3D map makePrintableDate =
x</FONT>
</P>

<P><FONT SIZE=3D2>--</FONT>
<BR><FONT SIZE=3D2>-- Make the date printable. Printable means a string =
consisting of</FONT>
<BR><FONT SIZE=3D2>-- dates in the form dd mm yyyy (more or less undoes =
the make sortable f x)</FONT>
<BR><FONT SIZE=3D2>--</FONT>
</P>

<P><FONT SIZE=3D2>makePrintableDate :: String -&gt; String</FONT>
<BR><FONT SIZE=3D2>makePrintableDate x =3D unwords (reverse (words =
x))</FONT>
</P>

<P><FONT SIZE=3D2>--</FONT>
<BR><FONT SIZE=3D2>-- Make all the dates sortable. Sortable means a =
string consisting of</FONT>
<BR><FONT SIZE=3D2>-- dates in the form yyyy mm dd</FONT>
<BR><FONT SIZE=3D2>--</FONT>
</P>

<P><FONT SIZE=3D2>makeSortableDates :: [[String]] -&gt; [String]</FONT>
<BR><FONT SIZE=3D2>makeSortableDates x =3D map makeSortableDate =
x</FONT>
</P>

<P><FONT SIZE=3D2>--</FONT>
<BR><FONT SIZE=3D2>-- Make the date sortable. Sortable means a string =
consisting of</FONT>
<BR><FONT SIZE=3D2>-- dates in the form yyyy mm dd</FONT>
<BR><FONT SIZE=3D2>--</FONT>
</P>

<P><FONT SIZE=3D2>makeSortableDate :: [String] -&gt; String</FONT>
<BR><FONT SIZE=3D2>makeSortableDate x =3D unwords (reverse x)</FONT>
</P>

<P><FONT SIZE=3D2>--</FONT>
<BR><FONT SIZE=3D2>-- Get the input from the given file</FONT>
<BR><FONT SIZE=3D2>--</FONT>
</P>

<P><FONT SIZE=3D2>getInput :: String -&gt; IO String</FONT>
<BR><FONT SIZE=3D2>getInput myfile</FONT>
<BR><FONT SIZE=3D2>&nbsp; =3D readFile myfile</FONT>
</P>

<P><FONT SIZE=3D2>--</FONT>
<BR><FONT SIZE=3D2>-- Seperate the input file into an list of =
Strings</FONT>
<BR><FONT SIZE=3D2>--</FONT>
</P>

<P><FONT SIZE=3D2>separateIntoLines :: String -&gt; [String]</FONT>
<BR><FONT SIZE=3D2>separateIntoLines str =3D lines str</FONT>
</P>

<P><FONT SIZE=3D2>--</FONT>
<BR><FONT SIZE=3D2>-- Transform all the lines into dates</FONT>
<BR><FONT SIZE=3D2>--</FONT>
</P>

<P><FONT SIZE=3D2>linesToDates :: [String] -&gt; [[String]]</FONT>
<BR><FONT SIZE=3D2>linesToDates x =3D map lineToDate x</FONT>
</P>

<P><FONT SIZE=3D2>--</FONT>
<BR><FONT SIZE=3D2>-- Transform the lines into dates</FONT>
<BR><FONT SIZE=3D2>--</FONT>
</P>

<P><FONT SIZE=3D2>lineToDate :: String -&gt; [String]</FONT>
<BR><FONT SIZE=3D2>lineToDate x =3D words x</FONT>
</P>
<BR>

<P><FONT SIZE=3D2>--</FONT>
<BR><FONT SIZE=3D2>-- Transform the dates into lines</FONT>
<BR><FONT SIZE=3D2>--</FONT>
</P>

<P><FONT SIZE=3D2>getOutput :: [String] -&gt; String</FONT>
<BR><FONT SIZE=3D2>getOutput x =3D unlines x</FONT>
</P>

<P><FONT SIZE=3D2>--</FONT>
<BR><FONT SIZE=3D2>-- Fix all the dates so that they are in the form 0x =
if x &lt; 10</FONT>
<BR><FONT SIZE=3D2>--</FONT>
</P>

<P><FONT SIZE=3D2>fixDates:: [String] -&gt; [String]</FONT>
<BR><FONT SIZE=3D2>fixDates x =3D map fixPrefixes x</FONT>
</P>

<P><FONT SIZE=3D2>--</FONT>
<BR><FONT SIZE=3D2>-- Fix the dates so that they are in the form 0x if =
x &lt; 10</FONT>
<BR><FONT SIZE=3D2>--</FONT>
</P>

<P><FONT SIZE=3D2>fixPrefixes :: String -&gt; String</FONT>
<BR><FONT SIZE=3D2>fixPrefixes p</FONT>
<BR><FONT SIZE=3D2>&nbsp;&nbsp; | p =3D=3D &quot;1&quot; &nbsp; =3D =
&quot;01&quot;</FONT>
<BR><FONT SIZE=3D2>&nbsp;&nbsp; | p =3D=3D &quot;2&quot;&nbsp;&nbsp; =
=3D &quot;02&quot;</FONT>
<BR><FONT SIZE=3D2>&nbsp;&nbsp; | p =3D=3D &quot;3&quot; &nbsp; =3D =
&quot;03&quot;</FONT>
<BR><FONT SIZE=3D2>&nbsp;&nbsp; | p =3D=3D &quot;4&quot;&nbsp;&nbsp; =
=3D &quot;04&quot;</FONT>
<BR><FONT SIZE=3D2>&nbsp;&nbsp; | p =3D=3D &quot;5&quot; &nbsp; =3D =
&quot;05&quot;</FONT>
<BR><FONT SIZE=3D2>&nbsp;&nbsp; | p =3D=3D &quot;6&quot;&nbsp;&nbsp; =
=3D &quot;06&quot;</FONT>
<BR><FONT SIZE=3D2>&nbsp;&nbsp; | p =3D=3D &quot;7&quot; &nbsp; =3D =
&quot;07&quot;</FONT>
<BR><FONT SIZE=3D2>&nbsp;&nbsp; | p =3D=3D &quot;8&quot;&nbsp;&nbsp; =
=3D &quot;08&quot;</FONT>
<BR><FONT SIZE=3D2>&nbsp;&nbsp; | p =3D=3D &quot;9&quot; &nbsp; =3D =
&quot;09&quot;</FONT>
<BR><FONT SIZE=3D2>&nbsp;&nbsp; | otherwise&nbsp; =3D p</FONT>
</P>

<P><FONT SIZE=3D2>--</FONT>
<BR><FONT SIZE=3D2>-- Quicksort the List of strings</FONT>
<BR><FONT SIZE=3D2>--</FONT>
</P>

<P><FONT SIZE=3D2>qsort :: [String] -&gt; [String]</FONT>
<BR><FONT SIZE=3D2>qsort []&nbsp;&nbsp;&nbsp;&nbsp; =3D []</FONT>
<BR><FONT SIZE=3D2>qsort (x:xs) =3D qsort elts_lt_x ++ [x] ++ qsort =
elts_greq_x</FONT>
<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; =
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<FONT SIZE=3D2> =
where</FONT>
<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; =
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <FONT SIZE=3D2>&nbsp;&nbsp; =
elts_lt_x&nbsp;&nbsp; =3D [y | y &lt;- xs, y &lt; x]</FONT>
<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; =
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <FONT SIZE=3D2>&nbsp;&nbsp; =
elts_greq_x =3D [y | y &lt;- xs, y &gt;=3D x]</FONT>
</P>

<P><FONT SIZE=3D2>--</FONT>
<BR><FONT SIZE=3D2>-- Write the ouput string to a file</FONT>
<BR><FONT SIZE=3D2>--</FONT>
</P>

<P><FONT SIZE=3D2>writeTheFile :: String -&gt; IO()</FONT>
<BR><FONT SIZE=3D2>writeTheFile x =3D writeFile &quot;output.txt&quot; =
x</FONT>
</P>
<BR>
<BR>
<BR>
<BR>
<BR>
<BR>

<P><FONT =
SIZE=3D2>_______________________________________________________________=
__</FONT>
<BR><FONT SIZE=3D2>Chat with friends online, try MSN Messenger: <A =
HREF=3D"http://messenger.msn.com" =
TARGET=3D"_blank">http://messenger.msn.com</A></FONT>
</P>

<P><FONT =
SIZE=3D2>_______________________________________________</FONT>
<BR><FONT SIZE=3D2>Haskell-Cafe mailing list</FONT>
<BR><FONT SIZE=3D2>Haskell-Cafe@haskell.org</FONT>
<BR><FONT SIZE=3D2><A =
HREF=3D"http://www.haskell.org/mailman/listinfo/haskell-cafe" =
TARGET=3D"_blank">http://www.haskell.org/mailman/listinfo/haskell-cafe</=
A></FONT>
</P>

</BODY>
</HTML>
------_=_NextPart_001_01C1CBC5.2DD9D150--