I try to find a solution on an exercise of my own, with the following requirements :
Here are the possible actions : F, L, R
A sequence is then represented by a string, like this :
"FFLRLFF"
I want to parse the above sequence (and handle errors) and then bind each action to a function, like this :
parseAction :: Char -> Either String (a -> a)
parseAction 'F' = Right moveForward
parseAction 'L' = Right turnLeft
parseAction 'R' = Right turnRight
parseAction s = Left ("Unkown action : " ++ [s])
-- Implementation omitted
moveForward :: a -> a
turnLeft :: a -> a
turnRight :: a -> a
Now what I want is something with the following signature :
parseSequence :: String -> Either String [(a -> a)]
I want to parse a full sequence by using many times parseAction
function, and fails when that one returns Left. I'm stuck on how can I implement this function.
Do you have any ideas ?
This looks like
mapM :: Monad m => (a -> m b) -> [a] -> m [b]
where
a ~ Char
b ~ (a -> a)
m ~ (Either String)
So an implementation is simply:
parseSequence :: String -> Either String [a -> a]
parseSequence = mapM parseAction
As an aside, note that your parseAction
doesn't really want to be using type (a -> a)
, which must work for any type a
, chosen by the person calling the function. You instead want it to use type (Location -> Location)
, where Location is whatever type you're using to represent the location of the object you're moving.
Equivalently to mapM, you can (as suggested by duplode) instead use traverse, which is slightly more general. In recent versions of GHC traverse is in Prelude; in older versions you may have to import it from Data.Traversable to use it.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With