I tried to write the program in Haskell that will take a string of integer numbers delimitated by comma, convert it to list of integer numbers and increment each number by 1
Just for fun, here is how you could create a simple parser with Parsec:
module Main where
import Control.Applicative hiding (many)
import Text.Parsec
import Text.Parsec.String
line :: Parser [Int]
line = number `sepBy` (char ',' *> spaces)
number = read <$> many digit
One advantage is that it's easily create a parser which is flexible in what it will accept:
*Main Text.Parsec Text.Parsec.Token> :load "/home/mikste/programming/Temp.hs"
[1 of 1] Compiling Main ( /home/mikste/programming/Temp.hs, interpreted )
Ok, modules loaded: Main.
*Main Text.Parsec Text.Parsec.Token> parse line "" "1, 2, 3"
Right [1,2,3]
*Main Text.Parsec Text.Parsec.Token> parse line "" "10,2703, 5, 3"
Right [10,2703,5,3]
*Main Text.Parsec Text.Parsec.Token>
This is a bit of a hack, but heck, it works.
yourFunc str = map (+1) $ read ("[" ++ str ++ "]")
Here is a non-hack version using unfoldr
:
import Data.List
import Control.Arrow(second)
-- break' is like break but removes the
-- delimiter from the rest string
break' d = second (drop 1) . break d
split :: String -> Maybe (String,String)
split [] = Nothing
split xs = Just . break' (==',') $ xs
yourFunc :: String -> [Int]
yourFunc = map ((+1) . read) . unfoldr split
This is application of HaskellElephant's answer to original question with minor changes
splitByDelimiter :: Char -> String -> [String] splitByDelimiter = unfoldr . splitSingle splitSingle :: Char -> String -> Maybe (String,String) splitSingle _ [] = Nothing splitSingle delimiter xs = let (ys, zs) = break (== delimiter) xs in Just (ys, drop 1 zs)
Where the function splitSingle split the list in two substrings by first delimiter.
For example:
"1,2,-5,-23,15" -> Just ("1", "2,-5,-23,15")
splitBy del str = helper del str []
where
helper _ [] acc = let acc0 = reverse acc in [acc0]
helper del (x:xs) acc
| x==del = let acc0 = reverse acc in acc0 : helper del xs []
| otherwise = let acc0 = x : acc in helper del xs acc0
Another without imports:
splitBy :: Char -> String -> [String]
splitBy _ [] = []
splitBy c s =
let
i = (length . takeWhile (/= c)) s
(as, bs) = splitAt i s
in as : splitBy c (if bs == [] then [] else tail bs)
import qualified Text.Regex as RegExp
myRegexSplit :: String -> String -> [String]
myRegexSplit regExp theString =
let result = RegExp.splitRegex (RegExp.mkRegex regExp) theString
in filter (not . null) result
-- using regex has the advantage of making it easy to use a regular
-- expression instead of only normal strings as delimiters.
-- the splitRegex function tends to return an array with an empty string
-- as the last element. So the filter takes it out
-- how to use in ghci to split a sentence
let timeParts = myRegexSplit " " "I love ponies a lot"