I am writing a function that takes a predicate p
and a list. It
returns ([value],[state])
where the first list contains elements that pass p
and the second contains the elements that do not. However, when I run
runState (myFunc even [1,2,3,4,5]) []
I get ([2,4,5,3,1],[5,3,1])
where the failed elements are incorrectly being stored in [value]
. I believe this is due to get
updating both state and value, but I haven't been able to find a way to update just the state and leave the value alone so I was wondering how I would do 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 myFunc _ []
definition is indeed putting the state into the value. You actually 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
side cool way to write it even though it’s probably an exercise in state and partition
already exists,
import Data.Bifunctor
partition f = foldr m ([], [])
where m x = (if f x then first else second) (x:)