2013-07-07 17 views
0

我使用Control.Monad.Rand,我有一個結構將Rand monad帶出`data`構造?

data MCSystem = MCSystem { params :: Params 
         , path :: Path } 

和功能,我不知道如何實現 -

runSystem :: (RandomGen g) => MCSystem -> Rand g MCSystem 
runSystem system = MCSystem mcparams newPath -- this line doesn't make any 
              -- sense and i know it 
    where 
    mcparams = params system 
    newPath = runPath $ path system 

runPath :: (RandomGen g) => Path -> Rand g Path 
-- basically performs a random mutation on the path 

runPath返回Rand g Path單子......如何我是否需要將它作爲新的Rand g MCSystem monad,以便runSystem能夠正確返回它,並且稍後可以使用生成器來調用它?

我想也許我可以重構一個閱讀器monad的一切,但我覺得我想避免它,如果可能的話。

回答

3

Rand是Monad的一個實例,可以以Monad的所有方式使用。就像任何其他monad一樣,您「獲得價值」,並使用>>=對其進行操作。

例如,這適用於runSystem的定義:

runSystem system = runPath (path system) >>= \newPath -> return (MCSystem (params system) newPath) 

在做語法使它更好:

runSystem system = do 
    newPath <- runPath (path system) 
    return $ MCSystem (params system) newPath 

但最好的方式來使用Rand應用性的實例:

runSystem system = MCSystem <$> pure (params system) <*> runPath (path system) 

但是,如果您還沒有了解應用類,這可能沒有多大意義(如果是這種情況,其他解決方案都可以)。

編輯:其實,你真正需要的是Functor類型類,所以這也適用,並且是最好的,你可以得到:

runSystem system = MCSystem (params system) <$> runPath (path system) 

基本上你是包裝的runPath (path system)結果周圍MCSystem

+0

我覺得有點傻,我實際上在程序的另一部分中使用了符號方法,但在這種情況下,我是「重構」以隨機添加,並且被我已經寫入的函數式樣蒙上了一層陰影。 –

+0

但在某種程度上,應用風格似乎更具表現力。你有沒有什麼好的參考來開始適用於程序設計? –

+0

一個很好的指導是在學習你一個haskell教程中的[Functors,Applicative Functors和Monoid章節](http://learnyouahaskell.com/functors-applicative-functors-and-monoids)。 –