静岡Developers勉強会 第4回Haskell読書会に参加しました。

静岡Developers勉強会 第4回Haskell読書会に参加した皆さんお疲れ様でした。

http://farm5.static.flickr.com/4033/4547322085_4ae2b91111.jpg

講義録について

前の生成器の値を、後の生成器の値として利用できる

Hugs> [ (x, y) | x <- [1..3], y <- [x..3]]
[(1,1),(1,2),(1,3),(2,2),(2,3),(3,3)]
  • xsはxのセットだからxs
  • xssはxsのセットだからxss

なるほど。

問. 2つのサイコロの出目の組み合わせの数を、リスト内容を使って求めよ。

Hugs> length [(x,y)| x<- [1..6],y<- [1..6]]
36

問.組のリストから各組の2番目の要素を取り出すsecondsを定義せよ。

seconds    :: [(a,b)] -> [b]
seconds ps =  [ y | ( _ , y ) <- ps]

Main> seconds [(2,3),(3,3),(4,2)]
[3,3,2]

ワイルドカードを使って、捨て変数を使うという考え方がHaskellらしい考え方ですね。

練習問題

問1.

sumOne2Hundred = sum [ x*x | x <- [1..100]]

問2.
ここでもワイルドカードを使い、n回繰り返すのは[1..n]の値を捨てるという考えに基づく。
ワイルドカードのn個の値に持つリストに、xを代入するという考え」。

myreplicate :: Int -> a -> [a]
myreplicate n x = [x | _ <- [1..n]] 

yを捨て変数として計算する方法もある。ただし、変数を何も使用しないとエラーが出ることがある。

myreplicate :: Int -> a -> [a]
myreplicate n x = [x | y <- [1..n]] 

無限のリストを生成し、takeで必要な分だけ取る方法もある。

myreplicate2 :: Int -> a -> [a]
myreplicate2 n x = take n (repeat x)

今後、使う約数を求める関数factorsを定義する。

factors :: Int -> [Int]
factors n = [x| x <- [1..n], n `mod` x == 0]

関数factorsを用いて、整数が素数か否かを判定する関数primeを定義する。

prime :: Int -> [Int]
prime n = factors n == [1,n]

この関数primeを用いて2つの場合を計算する。

Main> prime 2147483646
False

2の倍数なので、factorsが[1,2,]を返した時点で、遅延評価で値が返る。

Main> prime 2147483647
^C{Interrupted!}

値は返ってこない。いつまでたっても返ってこない。

ガードの話

ガードがTrueの場合のみ、値をリストに追加する。
ある値までの素数を返す関数primesを定義する。ここでは、関数primeをガードとして利用している。

primes   :: Int -> [Int]
primes n =  [ x | x <- [2..n], prime x]
Main> primes 1 #処理系が空リストを返す
[]
Main> primes 2
[2]
Main> primes 3
[2,3]
Main> primes 4
[2,3]
Main> primes 5
[2,3,5]

ハッシュのような使い方ができる関数findを定義する

find ::Eq a => a -> [(a,b)] -> [b]
find k t = [v | (k',v) <- t, k == k'] 
Main> find '2' [('2',5),('1',3),('2',1),('3',4)]
[5,1]

リストの隣の値との組を生成する関数pairsを定義する。

pairs    :: [a] -> [(a,a)]
pairs xs =  zip xs ( tail xs )
Main> pairs [1,2,3,4]
[(1,2),(2,3),(3,4)]

あるキーがリストのどの位置にあるかを出力する関数positionsは次のとおり。

positions :: Eq a => a -> [a] -> [Int]
positions x xs = [i | (x',i) <- zip xs [0..n], x == x']
                 where n = length xs - 1
Main> positions False [True,False,True,False]
[1,3]
練習問題その2

問3.

pyths :: Int -> [(Int,Int,Int)]
pyths n = [(x,y,z)| x <- [1..n],y <- [1..n], z <- [1..n],x^2 + y^2 == z^2]
Main> pyths 10
[(3,4,5),(4,3,5),(6,8,10),(8,6,10)]

問4.

factors   :: Int -> [Int]
factors n =  [x | x <- [1..n], n`mod`x == 0] 

perfects   :: Int -> [Int]
perfects n =  [x | x <- [1..n], sum (init (factors x)) == x]

問5.

concat2 = concat[[(x,y) | y <- [4,5,6]] |x <- [1,2,3]]

外側のxから評価しているのでいいのかな?

問6.

find     :: Eq a => a -> [(a,b)] -> [b]
find k t =  [v | (k', v) <- t, k == k']

positions      :: Eq a => a -> [a] -> [Int]
positions x xs =  find x (zip xs [0..n])
                  where  n = length xs - 1 

問7.

scalarproduct :: [Int] -> [Int] -> Int
scalarproduct xs ys = sum [x*y |(x,y) <- zip xs ys]

今後について

次回の静岡Developers勉強会 第5回Haskell読書会は静岡で開催。Ustreamして、webから見てもらうのはいかがでしょう?
遠い先の話ですが、「Haskell読書会が終わった後、何をするか。」と帰りの電車の中でやじゅさんと話していました。
個人的にはアルゴリズムの本を読みたいのですが、Erlangなど別の関数型言語を学ぶのもいいですね。でも、一番よいのは、こういった「集まる場所」があるということで、今日は落ち着きました。

オマケ

今週は写真が保存されていなかったため、おやすみ。