[Haskell-beginners] Help with meaningful error message...
Daniel Fischer
daniel.is.fischer at googlemail.com
Wed Jun 8 00:31:36 CEST 2011
On Tuesday 07 June 2011, 23:54:18, Sean Charles wrote:
> On 07/06/11 22:50, aditya siram wrote:
> > I think the parse error is here:
> >
> > forwardRoutes m [] = m
> > forwardRoutes m (row:rows) =
> >
> > case M.lookup m (row !! 0) of
> >
> > Just route -> M.update m (row !! 1):route
> > Nothing -> M.insert from []
> >
> > forwardRoutes m rows<----------------- you probably want to remove
> > this line
>
> If I do that, how does my recursive function call itself again?
>
> I think it is badly broken in the syntax!
> In the last five minutes I have progressed to ...
>
>
> forwardRoutes :: M.Map String [String] -> [Record] -> M.Map
> forwardRoutes m [] = m
> forwardRoutes m (row:rows) =
> case M.lookup m (row !! 0) of
> Just route -> M.update m (row !! 1):route
> Nothing -> M.insert (row!!0) []
> forwardRoutes m rows
>
> but I think it ought to be...
>
>
> forwardRoutes :: M.Map String [String] -> [Record] -> M.Map
> forwardRoutes m [] = m
> forwardRoutes m (row:rows) =
> case M.lookup m (row !! 0) of
> Just route -> forwardRoutes (M.update m (row !! 1):route) rows
> Nothing -> forwardRoutes (M.insert (row!!0) []) rows
Much closer. Now you have a recursion and it can be parsed. The error will
now arise in type-checking.
You've flipped the arguments in the lookup.
In the `Just' case, (M.update m (row !! 1):route) is parsed as
(M.update m (row !! 1)) : route
which is a list, not a map. You'll need to parenthesize thus:
((row !! 1) : route)
However,
Prelude> :t Data.Map.update
Data.Map.update
:: Ord k =>
(a -> Maybe a) -> k -> Data.Map.Map k a -> Data.Map.Map k a
so there's more to change in that branch. It seems that if (row !! 0) is a
key in the map, you want to modify the associated value by prepending
(row !! 1) to it. That would be achieved by
(M.update (\_ -> Just ((row !! 1):route)) (row !! 0) m)
But you don't use the value associated to the key here [you could, but
you've already looked that up before], so update is probably the wrong
function here, try
(M.insert (row !! 0) ((row !! 1) : route) m)
In the `Nothing' branch, you've omitted the map in which to insert.
forwardRoutes m (row@(h:t):rows) =
case M.lookup h m of
Just route -> forwardRoutes (M.insert h (head t:route) m) rows
Nothing -> forwardRoutes (M.insert h [] m) rows
would do what I think you want.
But it'd better be written as a fold,
forwardRoutes m rows = Data.List.foldl' update1 m rows
-- you can leave off the arguments if you wish
Now, update1 is the single-row update function, e.g.
update1 m [] = m -- empty row, do nothing
update1 m (x:xs) =
case M.lookup x m of
Nothing -> M.insert x [] m
Just route
| null xs -> ? -- what then?
| otherwise -> M.insert x (head xs:route) m
More information about the Beginners
mailing list