モナドを使う為のメモです.

IORefモナド

Haskellで参照を扱う為のモナド.
すごく便利だと感じるのは,頭の中がHaskellよりもC/C++等用に最適化されているから??

公式のドキュメント

サンプル

import Data.IORef

inc::IORef Int->IO ()
inc r =modifyIORef r (+1) --これが出来るのもIORefならでは

main :: IO ()
main = do
    num <- newIORef 0
    num2<- return num
    
    readIORef num >>= print
    readIORef num2>>= print
    
    inc num
    readIORef num >>= print
    readIORef num2>>= print --numへのmodifyがnum2の値にも影響する

実行結果

>runhugs test.hs
0
0
1
1

Cで書くと?

Cの読める人にとっては一番わかり易い説明だと思います.

#include <stdio.h>

void inc(int*r)
{
    (*r)++;            //modifyIORef r (+1)
}

void main()
{
    int n=0;        //num <- newIORef 0 (2行合わせて)
    int*num =&n;
    int*num2=num;        //num2<- return num
        
    printf("%d\n", *num);    //readIORef num >>= print
    printf("%d\n", *num2);    //readIORef num2>>= print
    
    inc(num);        //inc num
    printf("%d\n", *num);    //readIORef num >>= print
    printf("%d\n", *num2);    //readIORef num2>>= print
}

説明

新しく参照を作る newIORef
参照先の値を変更する modifyIORef
参照先の値を得る readIORef

Stateモナド

状態を持った計算をするのに便利なモナド.

公式のドキュメント

サンプル

import Control.Monad.State

getNext::State Int Int
getNext = do
    n <- get
    put $ n+1
    return n

main :: IO ()
main = do
    print hoge
    print hoge

hoge = evalState (do
            n0<-getNext
            n1<-getNext
            n2<-getNext
            n3<-getNext
            return [n0,n1,n2,n3]) 1

実行結果

>runghc test.hs
[1,2,3,4]
[1,2,3,4]

説明

状態の束縛を自分で

nextState::Zyotai->(Kekka, Zyotai)
nextState=.......
       :
       :
(ret0, state0)<- nextState firstState
(ret1, state1)<- nextState state0
(ret2, state2)<- nextState state1

と自分で書くのはめんどくさいですが

nextState::State Zyotai Kekka
nextState=.......
       :
       :
ret0<- nextState firstState
ret1<- nextState state0
ret2<- nextState state1

と少しシンプルにする事ができます.使い方が正しいのか自信が無いです...
IORefやMaybeモナドのような派手さが無いです^^;

コメント


お名前: