State Monad:修改状态而不修改值
State Monad: Modifying state without modifying value
我正在编写一个带有谓词 p
和列表的函数。它
returns ([value],[state])
其中第一个列表包含通过 p
的元素,第二个包含未通过的元素。然而,当我 运行
runState (myFunc even [1,2,3,4,5]) []
我得到 ([2,4,5,3,1],[5,3,1])
,其中失败的元素被错误地存储在 [value]
中。我相信这是由于 get
更新了状态和值,但我一直无法找到一种方法来更新状态而单独保留值,所以我想知道我将如何做到这一点。
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
你的myFunc _ []
定义确实是把state放到了value里。你实际上只是希望它是一个空的通行证列表:
myFunc _ [] = return []
然后您可能希望 return 按顺序排列结果:
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
虽然它可能是状态练习并且 partition
已经存在,但它的编写方式很酷,
import Data.Bifunctor
partition f = foldr m ([], [])
where m x = (if f x then first else second) (x:)
我正在编写一个带有谓词 p
和列表的函数。它
returns ([value],[state])
其中第一个列表包含通过 p
的元素,第二个包含未通过的元素。然而,当我 运行
runState (myFunc even [1,2,3,4,5]) []
我得到 ([2,4,5,3,1],[5,3,1])
,其中失败的元素被错误地存储在 [value]
中。我相信这是由于 get
更新了状态和值,但我一直无法找到一种方法来更新状态而单独保留值,所以我想知道我将如何做到这一点。
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
你的myFunc _ []
定义确实是把state放到了value里。你实际上只是希望它是一个空的通行证列表:
myFunc _ [] = return []
然后您可能希望 return 按顺序排列结果:
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
虽然它可能是状态练习并且 partition
已经存在,但它的编写方式很酷,
import Data.Bifunctor
partition f = foldr m ([], [])
where m x = (if f x then first else second) (x:)