スポンサーサイト

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。

[Haskell]StateTでカード分配

StateTの勉強のため、52枚のカードを分配するコードを書いてみました。

import Control.Monad.State
import Random
import List

main = do
(a, cs1) <- runStateT (pickCards 13) [1..52]
(b, cs2) <- runStateT (pickCards 13) cs1
(c, cs3) <- runStateT (pickCards 13) cs2
(d, cs4) <- runStateT (pickCards 13) cs3
-- 分配したカード
print a
print b
print c
print d
-- 残ったカード
print cs4

pickCard :: StateT [Int] IO Int
pickCard = do
c <- liftIO $ randomRIO (1,52)
cs <- get
if elem c cs
then put (delete c cs) >> return c
else pickCard

pickCards :: Int -> StateT [Int] IO [Int]
pickCards n = do
c <- pickCard
cs <- get
if n - 1 > 0 && (not . null) cs
then pickCards (n - 1) >>= \cs' -> return $ c:cs'
else return [c]


1?52の数値を持つリストを状態として引き継ぎながら
ランダムに取得した数値をリストから削り、返却するという流れで考えました。

getは状態の取得、putは新たな状態の保存、runStateTに状態の初期値を与えて
関数を走らせ、更新された状態を次の処理へ繋ぐ。

ランダムの値を取得するときに、IOモナドに包まれて値が戻されるので
liftIOを使用してStateTモナドで包んでやる、と理解しました、が合ってるのかな。

実際に使ってみると、なんとなく感覚がつかめてきたかも。

コメントの投稿

非公開コメント

プロフィール

jou4

Author:jou4
FC2ブログへようこそ!

最新記事
最新コメント
最新トラックバック
月別アーカイブ
カテゴリ
検索フォーム
RSSリンクの表示
リンク
ブロとも申請フォーム

この人とブロともになる

QRコード
QRコード
上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。