State Monad: change state without changing value

I am writing a function that takes a predicate p

and a list. This returns ([value],[state])

where the first list contains the elements that go through p

and the second contains the elements that don't. However, when I run

runState (myFunc even [1,2,3,4,5]) [] 

      

I am getting ([2,4,5,3,1],[5,3,1])

where erroneous items are not being stored correctly in [value]

. I suppose it has to do with get

updating the state and value, but I couldn't find a way to update only the state and leave the value alone, so I was wondering how I would go about doing that.

myFunc :: (a->Bool) -> [a] -> State [a] [a]
myFunc _ [] = do
  a <- get
  return a
myFunc p (x:xs) = do
    if (p x) then do
      s <- myFunc p xs
      let ret = (x:s)
      return ret
    else do
      s <- get
      put(x:s)
      myFunc p xs

      

+3


source to share


1 answer


Your definition myFunc _ []

really puts the state in the meaning. You just want it to be an empty list of passes:

myFunc _ [] = return []

      

and then you probably want to return the results in order:



myFunc :: (a -> Bool) -> [a] -> State [a] [a]
myFunc _ [] = return []
myFunc p (x:xs) = do
    passes <- myFunc p xs

    if p x then
        return (x:passes)
    else do
        modify (x:)
        return passes

      

bock is a cool way to write it down, although its probably an exercise in the state and partition

already exists,

import Data.Bifunctor

partition f = foldr m ([], [])
    where m x = (if f x then first else second) (x:)

      

+2


source







All Articles