0

を使用しControl.Monad.Randており、構造があります

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モナドを作成し、runSystemそれを適切に返すことができ、後でジェネレーターで呼び出すことができるようにするにはどうすればよいですか?

おそらくすべてを Reader モナドにリファクタリングできると思いますが、できれば避けたいと思っています。

4

1 に答える 1

3

Randはモナドのインスタンスであり、モナドができるすべての方法で使用できます。他のモナドと同じように、「値を取得」し、 を使用して操作し>>=ます。

たとえば、これは runSystem の定義に対して機能します。

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

do 構文はそれをより良くします:

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

Randただし、アプリケーション インスタンスを使用する最善の方法は次のとおりです。

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

ただし、Applicative クラスについてまだ学んでいない場合は、あまり意味がないかもしれません (その場合は、他のソリューションで問題ありません)。

編集:実際には、本当に必要なのは型クラスだけなFunctorので、これも機能し、入手できる最高のものです:

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

基本的に、結果をラップしていrunPath (path system)ますMCSystem

于 2013-07-07T08:32:28.750 に答える