2012-10-24 46 views
3

我一直在使用iteraterepeat以應用功能n次看到的解決方案。但是,我沒有設法在一個國家monad中使用它。綁定功能n次單子

此代碼:

-- Stuff an empty game level with obstacles. 
generateLevel :: Level -> State StdGen Level 
generateLevel lvl = 
    placeRandomWall lvl >>= placeRandomWall >>= placeRandomWall 

這一個工程,以及在意料之中:

generateLevel :: Level -> State StdGen Level 
generateLevel lvl = 
    placeRandomWall =<< placeRandomWall =<< placeRandomWall lvl 

然而,這是不一樣的:

generateLevel :: Level -> State StdGen Level 
generateLevel lvl = 
    (placeRandomWall =<< placeRandomWall =<< placeRandomWall) lvl 

最新抱怨類型。因此,我不能foldl (=<<) id (repeat 42 placeRandomWall),也不能我iterate

這是有道理的,因爲迭代採取a -> a功能,而我已經是a -> m a之類的東西。所以,我真的不知道該怎麼走。

編輯:我在哪裏寫repeat,我的意思是replicate

+2

**提示:**如果你有一個函數'˚F::一個 - >米A','(>> = F)::米 - >米A'可重複。 – hammar

+0

這可能是他們如何實現(> =>)。我會看看代碼,謝謝! – Niriel

回答

7

我認爲你正在尋找<=<>=>Control.Monad。他們可以摺疊在您使用replicate製作的列表中創建一個大動作。

嘗試foldr (<=<) return (replicate 42 placeRandomWall)

+0

現在閱讀有關這些操作員。我看到你偷偷地用摺疊器取代了我的foldl。我看了一下http://www.haskell.org/haskellwiki/Foldr_Foldl_Foldl%27,但它並沒有啓發我。任何喜歡foldr的理由? – Niriel

+0

它完美的工作,謝謝。克萊斯利的作品現在很有意義。 – Niriel

+3

@尼爾在這個特例中,foldl和foldr之間確實沒有區別。但總的來說,foldr允許更多的懶惰。所以我更喜歡它,只要我沒有理由使用foldl。 – Carl