[Haskell-beginners] Seeking some clarification...
Sean Charles
sean at objitsu.com
Sun Jun 5 20:46:41 CEST 2011
I have a CSV file containing some data about trains: stations from, to,
times etc. and I wanted to 'learn some more Haskell' and, to my
astonishment,
I have gotten thus far but I am not sure *why* it works or *how* I got
there! LMAO Here is the relevant code ...
====>
trains :: String -> IO ()
trains csvfile = do
legodata <- parseCSVFromFile csvfile
case legodata of
Left error -> print error
Right legodata -> mapM_ putStrLn (trainCodes legodata)
-- Assumes row 1 contains cell header information
-- Note: the train-code is always the third cell
trainCodes :: [Record] -> [String]
trainCodes = nub . map (!! 2) . tail
====>
I was chuffed with writing the trainCodes as a point-free function,
that sort of thing is getting a little easier to work with but I still
have real head-banging frustrations sometimes with seemingly simple
things, like looping and just printing stuff out, despite having taught
myself
LISP six years ago and Erlang in recent years! I quit!! I really do!!!
My confusion arises over: mapM_ putStrLn (traincodes legodata)
Given that: mapM_ :: Monad
<http://haskell.org/ghc/docs/6.12.2/html/libraries/base-4.2.0.1/Control-Monad.html#t%3AMonad>
m => (a -> m b) -> [a] -> m ()
<http://haskell.org/ghc/docs/6.12.2/html/libraries/ghc-prim-0.2.0.0/GHC-Unit.html#t%3A%28%29>
Here's how I read it: For any m that is a Monad, mapM_ takes a function
that "takes
an 'a' and returns it wrapped in a monad", a "list of a's" and returns a
"monad containing
'unit'", the empty-list LISP-() undefined voidy thing.
Given that: putStrLn :: String
<http://hackage.haskell.org/packages/archive/base/latest/doc/html/Prelude.html#t:String>
-> IO
<http://hackage.haskell.org/packages/archive/base/latest/doc/html/Prelude.html#t:IO>
()
<http://hackage.haskell.org/packages/archive/base/latest/doc/ghc-prim-0.2.0.0/GHC-Unit.html#t:-40--41->,
this means that 'a' is String and 'm b' is
IO () and my list of [a] is the result of calling 'traincodes legodata'.
trainCodes = nub . map (!! 2) . tail
legodata is [Record] (from Text.CSV) and so, 'tail' removes the header
row from
the data, 'map (!! 2)' extracts the third field from each row and
finally 'nub'
removes the duplicates. Thus the return type from trainCodes is [String].
Gluing it all together:
mapM_ :: Monad
<http://haskell.org/ghc/docs/6.12.2/html/libraries/base-4.2.0.1/Control-Monad.html#t%3AMonad>
m => (a -> m b) -> [a] -> m ()
<http://haskell.org/ghc/docs/6.12.2/html/libraries/ghc-prim-0.2.0.0/GHC-Unit.html#t%3A%28%29>
putStrLn :: String
<http://hackage.haskell.org/packages/archive/base/latest/doc/html/Prelude.html#t:String>
-> IO
<http://hackage.haskell.org/packages/archive/base/latest/doc/html/Prelude.html#t:IO>
()
<http://hackage.haskell.org/packages/archive/base/latest/doc/ghc-prim-0.2.0.0/GHC-Unit.html#t:-40--41->
trainCodes :: [Record] -> [String]
the type of my call then would seem to be:
String -> IO () -> [String] -> IO ()
"putStrLn" -> (trainCodes legodata) -> IO ()
which means that not only have I got the types correct for the call but
the result
type of 'IO ()' also satisfies the type return for my function and hence
it executes
from 'main' (where it is called from) with no issues.
So, am I finally beginning to get a grip on it all ? This list is a
constant source
of education and I don't post very often as you guys give me far too
much stuff to
be reading all the time! :)
I am using Text.CSV to read my file and all I wanted to do was to output
a list of unique codes from column three of the spreadsheet data, one per
line, so that I can use this Haskell as part of a bigger 'bash' script.
Any detailed explanations that might help me better understand my solution
would be welcome; right now I feel I 'just got lucky' although there must
be a glimmer of understanding somewhere! LOL
Thanks,
Sean.
PS: Phew!
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://www.haskell.org/pipermail/beginners/attachments/20110605/e3670f4e/attachment-0001.htm>
More information about the Beginners
mailing list