[Haskell-cafe] Returning a list element?

Robert Dockins robdockins at fastmail.fm
Mon Mar 20 18:19:17 EST 2006


On Mar 20, 2006, at 5:15 PM, Neil Rutland wrote:
> Hi there,
>
> thank you all for your help with regards to the integer addition  
> question that i asked yesterday it was very good in clarifying my  
> ideas. However i would now like to ask for your expert help once  
> again.
>
> Basically i have a list of 16 tuples of 12 elements each, each  
> tuple representing a train station - the tuple takes the form
>
> station = [string, int, int, bool, bool, bool, bool, bool, bool,  
> boo, bool, bool]
I think you'll be better off defining an enumerated type for your  
rail lines and then having each station contain a list of the lines  
to which it connects rather than trying to wrangle that huge tuple of  
booleans.  Something like:

data RailLine
       = Bakerloo | British | Central ....

type Station = (String,Int,Float,[RailLine])

victoriaLine :: [Station]
victoriaLine = [("Walthamstow Central", 1, 0, [British]), ... ]


Or, better:

type Station = (String,(Int,Float,[RailLine]))

because now you can use the standard list function 'lookup'.


Or, better still, use Data.Map:

http://www.haskell.org/ghc/docs/latest/html/libraries/base/Data-Map.html


> Basically i have a list called victoria line which is a list of 16  
> stations. What i want to do is access an element of the list so i  
> can check and output the value that it holds. I'll include all my  
> code below so you can see what i mean more as well as the attempt  
> that i have made to do just that - its the bit called bakerloo!
>
> import Prelude
>
> type Element0 = String
> type Element1 = Int
> type Element2 = Float
> type Element3 = Bool
> type Element4 = Bool
> type Element5 = Bool
> type Element6 = Bool
> type Element7 = Bool
> type Element8 = Bool
> type Element9 = Bool
> type Element10 = Bool
> type Element11 = Bool

This all is pretty unnecessary -- as a rule of thumb, introduce a  
type alias when it makes it easier to read or maintain the resulting  
code.  I don't think these help.

> type Station = [ (Element0, Element1, Element2, Element3, Element4,  
> Element5, Element6, Element7, Element8, Element9, Element10,  
> Element11) ]
>
> victoriaLine :: Station
>
> victoriaLine = [ ("Walthamstow Central", 1, 0, False, True, False,  
> False, False, False, False, False, False),
>           ("BlackHorse Road", 2, 3.0, False, True, False, False,  
> False, False, False, False, False),
>           ("Tottenham Hale", 3, 3.3, False, True, False, False,  
> False, False, False, False, False),
>        ("Seven Sisters", 4, 3, False, True, False, False, False,  
> False, False, False, False),
>               ("Finsbury Park", 5, 4.0, False, True, False, False,  
> False, False, False, False, True),
>        ("Highbury and islington", 6, 4.0, False, True, False,  
> False, False, False, False, False, False),
>               ("Kings Corss And St Pancras", 7, 3.3, False, True,  
> False, True, False, False, True, True, True),
>               ("Euston", 8, 1.3, False, True, False, False, False,  
> False, False, True, False),
>                ("Warren Street", 9, 2.0, False, False, False,  
> False, False, False, False, True, False),
>               ("Oxford Circus", 10, 1.45, True, False, True, False,  
> False, False, False, False, False),
>               ("Green Park", 11, 2.0, False, False, False, False,  
> False, True, False, False, True),
>               ("Victoria", 12, 2.3, False, True, False, False,  
> True, True, False, False, False),
>               ("Pimlico", 13, 1.0, False, False, False, False,  
> False, False, False, False, False),
>                ("Vauxhall", 14, 1.45, False, True, False, False,  
> False, False, False, False, False),
>               ("Stockwell", 15, 1.3, False, False, False, False,  
> False, False, False, True, False),
>               ("Brixton", 16, 2.0, False, True, False, False,  
> False, False, False, False, False) ]
>
>
> mainMenu :: IO()
> mainMenu = do
>   putStr"\n"
>   putStr"Welcome To the Victoria Line Timetable System\n"
>   putStr"Please Make A Choice from those Listed Below\n\n"
>   putStr"Detail Station Information = stationMenu\n"
>   putStr"For All Stations that link to the Bakerloo Line = Bakerloo\n"
>   putStr"For All Stations that link to British Rail Services =  
> British\n"
>   putStr"For All Stations that link to the Central Line = Central\n"
>   putStr"For All Stations that link to the Circle Line = Circle\n"
>   putStr"For All Stations that link to the District Line = District\n"
>   putStr"For All Stations that link to the Jubilee Line = Jubilee\n"
>   putStr"For All Stations that link to the Metropolitan Line =  
> Metropolitan\n"
>   putStr"For All Stations that link to the Northern Line = Northern\n"
>   putStr"For All Stations that link to the Piccadilly Line =  
> Piccadilly\n"
>   return()

FYI, putStrLn will automatically insert a newline for you, and the  
final 'return ()' is unnecessary.  My favorite idiom for this kind of  
thing is:

mainMenu = putStr $ unlines
   [ "line 1"
   , "line 2"
   , "line 3"
   ]

I think it's easier to read.

> stationMenu::IO()
> stationMenu = do
>   putStr"\n"
>   putStr"Please Select The station You are located at\n\n"
>   putStr"Walthamstow Central\n"
>   putStr"BlackHorse Road\n"
>   putStr"Tottenham Hale\n"
>   putStr"Seven Sisters\n"
>   putStr"Finsbury Park\n"
>   putStr"Higbury and Islington\n"
>   putStr"Kings Cross and St Pancras\n"
>   putStr"Euston\n"
>   putStr"Warren Street\n"
>   putStr"Oxford Circus\n"
>   putStr"Green Park\n"
>   putStr"Victoria\n"
>   putStr"Pimlico\n"
>   putStr"Vauxhall\n"
>   putStr"Stockwell\n"
>   putStr"Brixton\n"
>
> lineMenu::IO()
> lineMenu = do
>   putStr"\n"
>   putStr"Please Select The Line you wish to connect to\n"
>   putStr"Bakerloo Line = nrBakerloo\n"
>   putStr"British Rail = nrBritish\n"
>   putStr"Central Line = nrCentral\n"
>   putStr"Circle Line = nrCircle\n"
>   putStr"District Line = nrDistrict\n"
>   putStr"Jubilee Line = nrJubillee\n"
>   putStr"Metropolitan Line = nrMetropolitan\n"
>   putStr"Northern Line = nrNorthern\n"
>   putStr"Piccadilly Line = nrPicadilly\n"
>
> bakerloo :: Station->Element0->[Element3]
> bakerloo dBase findIt = do [ element3 | (element0, element1,  
> element2, element3, element4, element5, element6, element7,  
> element8, element9, element10, element11) <- dBase, element0 ==  
> findIt ]

I think that your problem here is that you are mixing the list  
comprehension and monadic syntax.  Delete the 'do' and I think it  
will work.  But you end up with a list of booleans, which is probably  
not what you want.

> stops:: Int->Int->Int
> stops x y = x-y
>
> main = do
>  mainMenu
>  putStr"\n\nTo Calculate the number of stops between your location  
> and destination enter stop location destination\n"
>  putStr"e.g. Stops 4 14\n"
>  return()
>
> So there it is - any help you can give would be great.
>
> Thanks for all your responses yesterday.
>
> Neil


Rob Dockins

Speak softly and drive a Sherman tank.
Laugh hard; it's a long way to the bank.
           -- TMBG




More information about the Haskell-Cafe mailing list