从`Rand StdGen X`中提取`X`

时间:2015-01-20 04:43:14

标签: haskell

从2013年起,在Yorgey教授的class教育作业12中,它提供了Battlefield数据类型。

type Army = Int

data Battlefield = Battlefield { attackers :: Army, defenders :: Army } deriving Show

对于第二个家庭作业问题,它要求实施randomrandomR功能。

    -- @author: Brent Yorgey
    first :: (a -> b) -> (a, c) -> (b, c)
    first f (a, c) = (f a, c)

instance Random Battlefield where
    random = first (\(as, ds) -> Battlefield as ds) . twoInts
    randomR = undefined -- TODO

我使用以下功能实现了上述random

randomBF :: Rand StdGen Battlefield
randomBF = getRandom

twoInts :: RandomGen g => g -> ((Army, Army), g)
twoInts gen = let (one, gen')  = random gen
                  (two, gen'') = random gen'
              in ((abs one, abs two), gen'')

我很好奇如何从Battlefield获得randomBF

我尝试了以下内容:

ghci> evalRandT randomBF (mkStdGen 5)
Identity (Battlefield {attackers = 7777369639206507645, defenders = 5955775402155530247})

然而,它被包裹在Identity中。我不确定那是什么。但是,如何在惯用的Haskell中提取Battlefield ...部分?

1 个答案:

答案 0 :(得分:2)

要从Identity monad中提取值,请使用runIdentity中的Data.Functor.Identity

您还可以使用:evalRand randomBF (mkStdGen 5)返回“战地”值。