2013-10-02 4 views
2

클래스 용 보드 게임을 쓰고 있습니다. Control.Monad.Loops에는 내가 원하는 것에 매우 가까운 iterateUntil 함수가 있습니다. 그러나, 나는 나의 행동이 매개 변수 (이 턴을위한 보드 상태이다.)를 가지기를 원한다. 그래서 나의 질문은 얼마나 관용적인가? 명시 적 재귀를 제거하기 위해 할 수있는 일이 있습니까?상태 매개 변수가있는 IterateUntil

iterateUntilIO :: (a -> IO a) -> a -> (a -> Bool) -> IO a 
iterateUntilIO action state predicate = if predicate state 
              then return state 
              else do 
               nextState <- action state 
               iterateUntilIO action nextState predicate 
+0

저는 이것이 훌륭하다고 생각합니다 - 루프를 결합 자로 캡슐화하는 아이디어는 훌륭합니다. 내가 자연스럽게 그것을 더 자연스럽게 만들 수있는 유일한 방법은'if .. then .. else' 대신에 가드를 사용하는 것입니다. 예 : 'iterateUntilIO 액션 상태 술어 | 술어 상태 = ... | 그렇지 않으면 = ...' – luqui

+0

아, 그리고 이것은 IO와 특별히 관련이 없습니다. 이것은 어떤 모나드에서도 작동합니다. 나는이 함수를 untilM이라고 부르며, 그것의 타입 시그니처를 (Monad m) => (a -> m a) -> a -> (a -> Bool) -> m a'로 주겠다. – luqui

+1

iterateUntilM이 아닌가요? –

답변

5

이것은 iterateUntilM 인 것처럼 보입니다.

iterateUntilIO :: (a -> IO a) -> a -> (a -> Bool) -> IO a 
iterateUntilIO action state predicate = iterateUntilM predicate action state 

이것은 또한 당신이 단순히 코드에서 iterateUntilMiterateUntilIO을 대체 할 수있는 의미 : 같은 기능을 쓸 수 있습니다.

관련 문제