{-# LANGUAGE PatternGuards #-} module ParseInput where import Data.Char (toLower) type FileNum = Int data UserReply = TakeFile FileNum | MoveToTrash | ShowDiff | ShowDiffWith FileNum | ShowDiffBetween FileNum FileNum | Skip | Quit | Help deriving Show type NumFiles = Int parseInput :: String -> NumFiles -> Maybe UserReply parseInput str numFiles = case map toLower str of ('t':rest) | [num] <- parseInts rest -> if validFileNum num then Just $ TakeFile num else Nothing | otherwise -> Nothing ('m':[]) -> Just MoveToTrash ('d':rest) -> case parseInts rest of [] -> if numFiles == 1 then Just ShowDiff else Nothing [num] -> if validFileNum num then Just $ ShowDiffWith num else Nothing [num1, num2] -> if validFileNum num1 && validFileNum num2 then Just $ ShowDiffBetween num1 num2 else Nothing _ -> Nothing ('s':[]) -> Just Skip ('q':[]) -> Just Quit ('h':[]) -> Just Help ('?':[]) -> Just Help _ -> Nothing where validFileNum num = num > 0 && num <= numFiles parseInts :: String -> [Int] parseInts str = go str where go str | [(int, rest)] <- reads str :: [(Int, String)] = int : go rest | otherwise = []