I'm trying to write a module that can take a string representation of a simple equation, and evaluate it. As a first step, I need to cut the equation into individual tokens; based on the "rules" of takePiece. I tried writing cutEqu as a fold, but ran into the problem that I'm not really folding over the string; I'm taking different sized pieces until it's exhausted. I could cheat and make it fold over a list of numbers equal to the length of the string, but that seems clumsy.
In most of the guides I've read, they note that explicit recursion is a rare occurrence once you understand implicit recursive patterns (like folds and maps), and this seems like a potentially common scenario, but can't find an appropriate standard function to handle it. How would someone go about writing something simple like cutEqu using implicit recursion? I'm sure I could figure out a simple function to encapsulate the behavior, but it not already existing in the standard library suggests that I may be thinking about the scenario wrong.
import Data.Char
isLit :: String -> Bool
isLit = isDigit . head
takePiece :: String -> (String,String)
takePiece str
| isLit str = break (not . isDigit) str
| otherwise = splitAt 1 str
cutEqu :: String -> [String]
cutEqu [] = []
cutEqu xs = let (p,rest) = takePiece xs in
p : cutEqu rest
Edit: Here's my attempt at writing it implicitly:
consumeWith :: ([a] -> ([b],[a])) -> [a] -> [[b]]
consumeWith _ [] = []
consumeWith f xs = let (t, rest) = f xs in
t : consumeWith f rest
cutEqu' :: String -> [String]
cutEqu' = consumeWith (takePiece)
But again, I'm concerned that anything like this isn't a standard function. Is there a better way of going about this?
The pattern is called unfoldr which has the type signature:
unfoldr :: (b -> Maybe (a, b)) -> b -> [a]
Your cutEq function can be written in terms of unfoldr like this:
import Data.List
cutEq' str = unfoldr go str
where go [] = Nothing
go xs = Just $ takePiece xs
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