モナドを使う為のメモです.
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の読める人にとっては一番わかり易い説明だと思います.
#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
状態を持った計算をするのに便利なモナド.
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モナドのような派手さが無いです^^;