Last active
May 5, 2023 03:00
-
-
Save ijames/18b9942c4672e206dbc32313c517d457 to your computer and use it in GitHub Desktop.
Exercism Haskell doesn't like the Text.Regex.Posix lib, but this passes the wordy tests!
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{-# OPTIONS_GHC -Wno-overlapping-patterns #-} | |
module WordProblem ( answer ) where | |
-- From the Exercism exercise: https://exercism.org/tracks/haskell/exercises/wordy | |
-- Trying to do this: | |
-- * in a non parsing, | |
-- * with a narrow domain thinking (x `op` y only) | |
-- import Text.Regex.Posix Cost me a couple hours!!! | |
-- I didn't try Text.Regex.PCRE.Heavy (pcre-heavy in the package.yaml) but I guess that would have worked. | |
-- There was NOTHING explaining why this was a problem. Quite the hitch! | |
import Text.Regex.TDFA ( (=~) ) | |
import Text.Read (readMaybe) | |
type MatchStuff = (String, String, String, [String]) | |
type Math = Int -> Int -> Int | |
type FnEtc = (Int -> Int, [String]) | |
answer :: String -> Maybe Int | |
answer question = getEq question >>= process | |
getEq :: String -> Maybe [String] | |
getEq s = | |
let (_, _, _, equations) = s =~ "What is (.*)\\?" :: MatchStuff | |
in case equations of | |
[a] -> Just (words a) | |
_ -> Nothing | |
process :: [String] -> Maybe Int | |
process [] = Nothing | |
process (n:rest) = (readMaybe n :: Maybe Int) >>= flip calc rest | |
calc :: Int -> [String] -> Maybe Int | |
calc acc [] = Just acc | |
calc acc etc = next etc >>= \(fn, ts) -> calc (fn acc) ts | |
next :: [String] -> Maybe FnEtc | |
next t = | |
case t of | |
("plus":n:ts) -> eval (+) n ts | |
("minus":n:ts) -> eval (-) n ts | |
("multiplied":"by":n:ts) -> eval (*) n ts | |
("divided":"by":n:ts) -> eval div n ts | |
[] -> Just ((+0), []) | |
_ -> Nothing | |
eval :: Math -> String -> [String] -> Maybe FnEtc | |
eval op n t = case m of | |
Nothing -> Nothing | |
Just num -> Just (flip op num, t) | |
where m = readMaybe n | |
-- (>>=) :: Maybe a -> (a -> Maybe b) -> Maybe b | |
-- (>>=) m g = case m of | |
-- Nothing -> Nothing | |
-- Just x -> g x |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment