Skip to content

Instantly share code, notes, and snippets.

@zhangchiqing
Created December 25, 2016 04:18
Show Gist options
  • Save zhangchiqing/410692077f7409806d8883d5dc81f969 to your computer and use it in GitHub Desktop.
Save zhangchiqing/410692077f7409806d8883d5dc81f969 to your computer and use it in GitHub Desktop.
StateMonad vs Folding
module Main where
import Prelude (Unit, negate, (==), (>>>), (-), (>), (+), ($), bind)
import Data.Foldable (traverse_, foldl)
import Data.String (toCharArray)
import Control.Monad.State (State, execState, modify)
import Control.Monad.Eff (Eff)
import Control.Monad.Eff.Console (CONSOLE, logShow)
match :: Int -> Char -> Int
match lefts '(' = lefts + 1
match lefts ')' = if lefts > 0 then lefts - 1
else -1
match lefts _ = lefts
matching' :: Int -> Array Char -> Int
matching' = foldl match
matching :: Array Char -> State Int Unit
matching = traverse_ \p -> modify \lefts -> match lefts p
testParens :: String -> Boolean
testParens = toCharArray >>> matching >>> (\n -> execState n 0) >>> (==) 0
testParens' :: String -> Boolean
testParens' = toCharArray >>> (\lefts -> matching' 0 lefts) >>> (==) 0
main :: forall e. Eff (console :: CONSOLE | e) Unit
main = do
logShow $ testParens "((()))" -- true
logShow $ testParens "((())" -- false
logShow $ testParens ")" -- false
logShow $ testParens' "((()))" -- true
logShow $ testParens' "((())" -- false
logShow $ testParens' ")" -- false
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment