2016-01-06 36 views
1

我有這樣的事情,這是工作:「迭代,直到」用單子

main = do 
    let p = something :: MyType 
    p' <- newP p 
    p'' <- newP p' 
    p''' <- newP p'' 
    print p''' 

看到這個模式?我想重複這個,直到滿足某個條件,或者直到最大迭代次數通過。

我發現Control.Monad.Loops.iterateUntil,但我無法讓它工作。下面的代碼我有(check看起來像這樣check :: MyType -> Bool):

main = do 
    let p = something :: MyType 
    let stopCondition (i, p) = i == 100 || check p 
    let run (i, p) = (i + 1, newP p) 
    p' <- iterateUntil stopCondition (run (0, p)) 
    print p' 

,它甚至沒有編譯。

請注意,重要的是每次運行這個東西時,run的結果會反饋到下一個迭代中(我不確定iterateUntil會這樣做)。

回答

4

它看起來像你想使用iterateUntilM它有(a -> Bool) -> (a -> m a) -> a -> m a類型,其中狀態類型a(Int, MyType)。然後run應該是這樣的:

let run (i, p) = fmap (\p' -> (i + 1, p')) (newP p) 

那麼你可以做

(_, p') <- iterateUntilM stopCondition run (0, p) 
+0

我得到的'run'編譯錯誤:「非類型變量參數的約束:MonadRandom((,) t)(使用FlexibleContexts來允許這一點)當檢查'運行'具有推斷類型「。任何想法爲什麼? (我測試了'type MyType = Int','check p = p == 0',以及一個'newP'的簡單函數,它只是從'p'中減去1] – cambraca

+0

@cambraca - 抱歉,您可以使用'fmap'而不是'>> =',請參閱更新。 – Lee

+0

完美的工作,謝謝!我會查找這兩個,我還沒有使用它們(剛開始Haskell ..) – cambraca