Haskell/解決方案/理解 Monad
外觀
| 這些解決方案適用於Haskell/理解 Monad的舊版本。有些練習在書中被省略,其他的被合併到其他章節。 |
| 練習 |
|---|
|
2. 使用章節中定義的randomNext、Seed和rollDie
rollNDice :: Int -> Seed -> ([Int], Seed)
rollNDice 0 seed = ([], seed)
rollNDice n seed = let (die, seed0) = rollDie seed
(rest, seed1) = rollNDice (n-1) seed0
in ((die : rest) ,
seed1)
該函式獲得第一個骰子和種子,然後遞迴呼叫自身以擲出 N 個骰子,一旦RollNDice到達基本情況,它就會反過來構建一個骰子列表。然後,該函式返回骰子列表和傳遞給基本情況的最終種子rollNDice 0 seed = ([], seed)。
3. 我們使用 mkStdGen 獲取計算機的隨機數生成器,併為它提供一個任意數字 232。首先,在檔案開頭使用import System.Random
type Seed = StdGen
rollDie1 :: Seed -> (Int, Seed) rollDie1 seed = randomR (1,6) seed
在 Prelude 中
Main> rollDie1 (mkStdGen 232) (3,1017593109 40692)
| 練習 |
|---|
|
1. 您之前已經見過(>>==)定義下面的所有內容。因此,直到那一點的所有內容都只是為了設定一切。我將>>=命名為>>==,將return命名為return1,因為本章專門使用bind和return來處理隨機數;而真正的bind和return更加通用,因此出於某些原因無法使用 -----------------> 在那裡。至少它有效;您還想從我這裡得到什麼?鮮血?
在檔案開頭使用import System.Random
type Seed = StdGen
type Random1 a = Seed -> (a, Seed)
rollDie :: Random1 Int
rollDie seed = randomR (1,6) seed
(>>==) :: Random1 a -> (a -> Random1 b) -> Random1 b
(>>==) m g = \seed0 ->
let (result1, seed1) = m seed0
(result2, seed2) = (g result1) seed1
in (result2, seed2)
return1 :: a -> Random1 a
return1 x = \seed0 -> (x, seed0)
rollNDice1 :: Int -> Random1 [Int]
rollNDice1 0 = return1 []
rollNDice1 n = rollDie >>== (\d1 -> rollNDice1 (n-1) >>== (\rest -> return1 (d1 : rest)))
在 prelude 中
*Main> rollNDice1 20 (mkStdGen 231) ([4,3,1,1,2,3,5,4,2,5,6,4,6,2,4,5,6,5,1,5],1927676552 238604751)
如果您想知道:您將(mkStdGen 232111)傳遞給rollNDice1,因為rollNDice 20本身只會建立一個Random1 [Int];您需要將新形成的Random1 [Int]傳遞一個種子,以(mkStdGen 242)的形式,才能讓它開始輸出隨機數。
| 練習 |
|---|
|
1.
putString :: String -> IO () putString [] = putChar '\n' putString (s:xs) = putChar s >> putString xs
| 練習 |
|---|
修正(>>=)的定義,以考慮State建構函式。您需要使用模式匹配來刪除State建構函式。 |
(State a) >>= f = State $ \s -> let (a',s') = a s
(State b) = f a'
in b s'
| 練習 |
|---|
|
a >>= f = State $ \s -> let (a',s') = runState a s
in runState (f a') s'