2017-04-04 10 views
3

술어 p과 목록을 사용하는 함수를 작성했습니다. 은 ([value],[state])을 반환합니다. 첫 번째 목록에는 p을 전달하는 요소가 포함되어 있고 두 번째 요소에는없는 요소가 들어 있습니다. 그러나, 나는 실패한 요소가 잘못 [value]에 저장되는 곳상태 모나드 : 값을 수정하지 않고 상태를 수정하는 중

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

내가 ([2,4,5,3,1],[5,3,1])를 얻을 실행합니다. 이것은 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 
+0

상태에서 운동과 partition 이미 존재, 당신의 예를 컴파일 할 수 있습니다! – Alec

+0

기본 케이스가 문제입니다. 또한 함수는'([value], [state])'를 반환하지 않고'State [a] [a]'를 반환합니다. 그러나, 당신이 그것을 바꾸고 싶다면, 그것도 기본 경우에있을 것입니다. – Alec

답변

2

myFunc _ [] 정의가 실제로 상태 값을 넣습니다. 당신은 실제로 그냥 패스의 빈리스트가되고 싶어요 :

myFunc _ [] = 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 

측면 멋진 방법을 쓰기 그들이 원하는대로하지 않으면이를 되돌릴 주시기 바랍니다 - 나는 몇 가지 코드 정렬 문제를 해결

import Data.Bifunctor 

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

상관 없다는 것을 알고 있지만, Control.Arrow 대신에'Data.Bifunctor'에서'first'를 가져 오는 것이 좋습니다. 상대적으로 새로운 하스켈 사용자는 'Bifunctor'가 '화살표'보다 무엇인지 이해하는 경향이 더 큽니다. – dfeuer

+0

@dfeuer 잘 부탁드립니다. – Ryan