<commit_before>type Stack = [Int]

pop' :: Stack -> (Int, Stack)
pop' (x:xs) = (x,xs)

push' :: Int -> Stack -> ((),Stack)
push' a xs = ((),a:xs)

stackManip' :: Stack -> (Int, Stack)
stackManip' stack = let
    ((),newStack1) = push' 3 stack
    (a ,newStack2) = pop' newStack1
    in pop' newStack2

-- > stackManip' [5,8,2,1]
-- (5,[8,2,1])


-- state Monad

newtype State s a = State { runState :: s -> (a,s) }

instance Functor (State s) where
  fmap f (State mx) = State (\s -> let (x,s') = mx s
                                   in (f x, s'))

instance Applicative (State s) where
  pure x = State $ \s -> (x,s)
  (State mf) <*> (State mx) = State $ (\s -> let (f,s') = mf s
                                                 (x,s'') = mx s'
                                             in (f x, s''))
instance Monad (State s) where
  return x = State $ \s -> (x,s)
  (State h) >>= f = State $ \s -> let (x,s') = h s
                                      (State y) = f x
                                  in y s' 

pop :: State Stack Int
pop = State $ \(x:xs) -> (x,xs)

push :: Int -> State Stack ()
push a = State $ \xs -> ((), a:xs)

stackManip :: State Stack Int
stackManip = do
  push 3
  pop  
  pop

--  runState stackManip [5,8,2,1]
--  (5,[8,2,1])


stackStuff :: State Stack ()
stackStuff = do
  a <- pop
  if a == 5
    then push 5
    else do
      push 3
      push 8

-- > runState  stackStuff [5,8,2,1]
-- ((),[5,8,2,1])
-- > runState  stackStuff [1,5,8,2,1]
-- ((),[8,3,5,8,2,1])




<commit_msg>add more examples<commit_after>type Stack = [Int]

pop' :: Stack -> (Int, Stack)
pop' (x:xs) = (x,xs)

push' :: Int -> Stack -> ((),Stack)
push' a xs = ((),a:xs)

stackManip' :: Stack -> (Int, Stack)
stackManip' stack = let
    ((),newStack1) = push' 3 stack
    (a ,newStack2) = pop' newStack1
    in pop' newStack2

-- > stackManip' [5,8,2,1]
-- (5,[8,2,1])


-- state Monad

newtype State s a = State { runState :: s -> (a,s) }

instance Functor (State s) where
  fmap f (State mx) = State (\s -> let (x,s') = mx s
                                   in (f x, s'))

instance Applicative (State s) where
  pure x = State $ \s -> (x,s)
  (State mf) <*> (State mx) = State $ (\s -> let (f,s') = mf s
                                                 (x,s'') = mx s'
                                             in (f x, s''))
instance Monad (State s) where
  return x = State $ \s -> (x,s)
  (State h) >>= f = State $ \s -> let (x,s') = h s
                                      (State y) = f x
                                  in y s' 

pop :: State Stack Int
pop = State $ \(x:xs) -> (x,xs)

push :: Int -> State Stack ()
push a = State $ \xs -> ((), a:xs)

stackManip :: State Stack Int
stackManip = do
  push 3
  pop  
  pop

--  runState stackManip [5,8,2,1]
--  (5,[8,2,1])


stackStuff :: State Stack ()
stackStuff = do
  a <- pop
  if a == 5
    then push 5
    else do
      push 3
      push 8

-- > runState  stackStuff [5,8,2,1]
-- ((),[5,8,2,1])
-- > runState  stackStuff [1,5,8,2,1]
-- ((),[8,3,5,8,2,1])


get :: State Stack Stack
get = State $ \s -> (s,s)

put :: Stack -> State Stack ()
put s = State $ \_ -> ((),s)

stackyStack :: State Stack ()
stackyStack = do
  stackNow <- get
  if stackNow == [1,2,3]
    then put [8,3,1]
    else put [9,2,1]

-- > runState stackyStack [1,2,3]
-- ((),[8,3,1])
-- > runState stackyStack [1,2,4]
-- ((),[9,2,1])




{'fraction_non_alphanumeric': 0.1927959846471804, 'fraction_numerical': 0.03277236492471213, 'mean_word_length': 1.756712774613507, 'pattern_counts': {'":': 0, '<': 8, '<?xml version=': 0, '>': 46, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 14, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5368897', 'n_tokens_mistral': 1349, 'n_tokens_neox': 1313, 'n_words': 400}