RHG

本日はRHGふつける読書会にきています。
今回のモナドからです。



以下メモ
x >>= f = concatMap f xs
[x] >>= f
concatMap f [x] -> map [f x]


[x] >>= f
concatMap f [x]
concat (map f [x])
[f x] -> f [(1,2)] -> []

IOモナドのところで評価と実行は違うということが話題になりました。

f:: (x,w) -> (b,w)
f:: a -> (w -> (b,w))
main = do <-getStdGen
	     let ns = take 3 (randoms g)
	     print (ns::[Int])

は次の二つのように書き換えられる

getStdGen >>= \g -> print (take 3 (radoms g))
getStddGen >>= rndoms >>> take 3 >>> put


ポイントフリースタイルの書き換え

f . g = \ x -> (g x)
f . g = \ x -> g (f x)

本日はSICP読書会

書いたソースとか

(define (count-leaves tree)
  (fold +
        0
        (map (lambda (x) (if (pair? x) (count-leaves x)
                             1))
             tree)))

(define (sum seq) (fold + 0 seq))

(define (dot-product v w)
  (sum (map * v w)))

(define (transpose mat)
  (fold-right (lambda (first rest)
                (if (null? rest) (map list first)
                    (map cons first rest)))
              '()
              mat))

(define (matrix-*-vect mat vec)
  (map (lambda (m) (dot-product m vec)) mat))

(define (matrix-*-matrix mat1 mat2)
  (map (lambda m1
         (map dot-product
              m1
              (transpose mat2)))
       mat1))
(define (matrix-+-matrix mat1 mat2)
  (map (lambda (x y) (map + x y))
       mat1
       mat2))

(define (reverse seq)
  (fold-right (lambda (x y) (append y (list x))) '() seq))
(define (reverse seq)
  (fold-left (lambda (x y) (cons x y)) '() seq))

Clean (o)

昨日のRHGでCleanの(o)を関数として定義するとどなるかと言う話題
でやってみたんですが。

モジュールトップレベルで定義すると、多重定義エラーになりました。
関数の中のwhere節で定義するとコンパイル通ります。

因みに(o)はStdFuncで以下のように定義されてます。

(o) infixr  9 // ::  u:(.a -> .b) u:(.c -> .a) -> u:(.c -> .b) // Function composition
(o) f g :== \ x -> f (g x)

Cleanでコッホ曲線

書いたよ。

以下そーす

Start world  
	# testwindow = Window "TestDraw" NilLS [WindowClose (noLS closeProcess)
	                                       ,WindowViewSize size
	                                       ,WindowLook True (\_ _ -> example6)
	                                       ,WindowViewDomain { corner1=origin,corner2=maxdomain }
	                                       ]
	
	= startIO  SDI Void (snd o openWindow undef testwindow) [ProcessClose closeProcess] world	

where
	size      = { w=500, h=500 }
	origin    = zero
	maxdomain = { x=origin.x+size.w, y=origin.y+size.h }

	example6 = fst o (coch 4 {x=0,y=200} 500.0 0.0)
	
	coch :: Int Point2 Real Real *Picture -> (*Picture,Point2)
	coch level point len  degree pic
		| level == 0   = let point` = (nextPoint point len degree) in ((drawLine point point` pic), point`)
		| otherwise  //  
			           # (pic,point) = coch (level-1) point len` degree   pic         
			           # degree             = degree+60.0
			           # (pic,point) = coch (level-1) point len` degree pic   
			           # degree             = degree+240.0					   
				   # (pic,point) = coch (level-1) point len` degree  pic  
			           # degree             = degree+60.0
		               = coch (level-1) point len` degree pic
	
		where 
			nextPoint current l deg = {x=x2,y=y2}
			where
			    // 最初この関数が悪さを… entier
				x2 = point.x + toInt (l * cos (toRadian (toReal deg)))
				y2 = point.y + toInt (l * sin (toRadian (toReal deg)))
			len` = len / 3.0

 	toRadian :: Real -> Real
 	toRadian a = a * PI  / 180.0
 	toDegree :: Real -> Real
 	toDegree a = a * 180.0 / PI



おまけ
"koichi"から"i"を除くと"koch"になるどうでもいいことに気づいてしまった…
以下Haskell

filter (not . (== 'i')) "koichi"


圏論勉強会の話題でHaskellでなにも考えずに
100万までのsumを求めるとHeap Errorになると言うので、Cleanでやってみた

import StdEnv

Start = sum [1..1000000]

結果

 1784293664

で、1000万で挑戦

 -2004260032

という風に符号付で表示されてしまう。
符号なしにするにはどうすばいいのだろうか?