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
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:)