我正在使用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
monad ...如何将其设为新的Rand g MCSystem
monad,以便runSystem
可以正确返回它,并且可以调用它后来用发电机?
我想也许我可以将所有内容重构为Reader monad,但我觉得如果可能的话我想避免它。
答案 0 :(得分:3)
Rand
是Monad的一个实例,可以用于monad的所有方式。就像任何其他monad一样,你“获得价值”,并使用>>=
对其进行操作。
例如,这适用于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)
但是,如果您还没有了解申请类,那可能没有多大意义(如果是这样的话,其他解决方案也没有问题)。
编辑:实际上,你真正需要的是Functor
类型类,所以这也有效,并且是你能得到的最好的:
runSystem system = MCSystem (params system) <$> runPath (path system)
基本上,您将runPath (path system)
的结果包裹在MCSystem