行列プログラマ in Haskell



[行列プログラマ](http://amzn.to/2gWImOH
)に登場するPythonをひたすらHaskellでかいてく。対応するPythonコードは書籍にて確認いただきたい。

# 0.4.1 確率分布

```haskell
> import Data.Map
> fromList [("heads", 1/2), ("tail", 1/2)] 
fromList [("heads", 1/2), ("tail", 1/2)]
  :: Fractional a => Map [Char] a
```

Pythonの辞書型に相当するものは Data.Mapかな。
他だいたい同じなので省略。

# 0.5.1 簡単な式

```haskell
> 44 + 11 * 4 - 6 / 11
87.45454545454545
```

---

## 課題 0.5.1: Python を使用して、1 週間が何秒かを求めよ

```haskell
> 7 * 24 * 60 * 60
604800
```

## 課題 0.5.2: Python を使用して、2304811 を 47 で割った余りを求めよ。ただし、% を使用しないこ と(ヒント://を用いる)。

```haskell
> (\y x -> y - (y `div` x) * x) 2304811 47
25
```

`%` の代わりとしては `rem`がある

## 文字列

```
> "This sentence is false."
"This sentence is false."
```

## 比較、条件、ブール値

```haskell
> 5 == 4
False
> 4 == 4
True
```

haskellだとブール演算は `&&` `||` `not`

```haskell
> True && False
False
> True && not (5 == 4)
True
```


### 課題 0.5.3: ブール式を入力して、673 と 909 の和が 3 で割り切れるかどうかを調べよ。

問題の意味がわからず。。。省略

ghci内であれば :t で値の方を調べられる

```haskell
> :t 4
4 :: Num t => t
> :t 4 == 4
4 == 4 :: Bool
> :t 
"4" :: [Char]
> :t 4 :: Float
4 :: Float
```

4の型は IntやFloatなど数字で扱える型になれることを出力している。
４をFloatとして使いたいなら型注釈をつければよい。

# 0.5.2 代入文

```haskell
> mynum = 4+1
```
---

Haskellでは普通は再代入不可能だがghci上だと可能

```haskell
> mynum = "Brow"
```

# 0.5.3 条件式

Haskellのifはelseが必須になる。

##  課題 0.5.4: −9 を x に、1/2 を y に代入する。以下の式の値を予想し、入力して予想を確認せよ。 2**(y+1/2) if x+10<0 else 2**(y-1/2)

条件は false 2 ** 0 で 1

```haskell
> (\x y -> if x + 10 < 0 then 2**(y+1/2) else 2**(y-1/2)) (-9  :: Int) (1/2)
1.0
```

# 0.5.4 集合

```haskell
> import Data.Set
> fromList [1+2, 3, 4]
fromList [3,4]
```

集合を表現するなら Data.Set

3が重複するのでひとつになってる。"a"は型が違うのでこのままでは一緒の集合にはできない。

```haskell
> import Data.Set
> length(fromList ['a','b','c','a','c'])
3
```

濃度はlengthで取得できる。

## 集計

```haskell
> import Data.Set
> sum(fromList [1,2,3])
6
```

## 集合の要素のテスト

```Haskell
> import Data.Set
> member 3 (fromList [1,2,3])
True
> member 4 (fromList [1,2,3])
False
> 4 `member` (fromList [1,2,3])
False
not . 4 `member` $ (fromList [1, 2, 3])
> True
```

## 集合の和集合、共通部分、差集合

```Haskell
> (fromList [1,2,3]) `union` (fromList [2,3,4])
fromList [1,2,3,4]
> (fromList [1,2,3]) `intersection` (fromList [2,3,4])
fromList [2,3]
> (fromList [1,2,3]) `difference` (fromList [2,3,4])
fromList [1]
```

## 集合の変更

```
> delete 2 . insert 4 . fromList $ [1,2,3]
```
fromList [1,3,4]

## 集合の内包表記

Setはモナドではななそうなので内包表記できそうにない。

```Haskell
> fromList [2*x | x <- [1,2,3]]
fromList [2,4,6]
```

### 課題 0.5.5: 集合 {1, 2, 3, 4, 5} に対する内包表記で、それぞれの整数の 2 乗を返すものを書け。

```Haskell
> fromList [x*x | x <- [1..5]]
fromList [1,4,9,16,25]
```

 課題0.5.6: 集合{0,1,2,3,4}に対する内包表記で、それぞれの整数を2の指数に持つ値、即ち、20、 21、22 などを返すものを書け。

```Haskell
> fromList [2 ^ x | x <- [0..4]]
fromList [1,2,4,8,16]
```

---

```Haskell
> fromList [x*x | x <- toList (fromList [1,3] `union` (fromList [5,7]))]
fromList [1,9,25,49]
```

```Haskell
> fromList [x*x | x <- toList (fromList [1,3] `union` (fromList [5,7])), x > 2]
fromList [9,25,49]
```

```Haskell
> fromList [x*y | x <- [1..3] , y <- [2..4]]
fromList [2,3,4,6,8,9,12]
```

### 課題 0.5.7

```Haskell
> fromList [x*y | x <- [1..3] , y <- [5,7,11]]
fromList [5,7,10,11,14,15,21,22,33]
```

---

```Haskell
> fromList [x*y | x <- [1..3] , y <- [2..4], x /= y]
fromList [2,3,4,6,8,12]
```

### 課題 0.5.8

```Haskell
> fromList [x*y | x <- [2,4,8] , y <- [3,6,12]]
fromList [6,12,24,48,96]
```

### 課題 0.5.9

```Haskell
> [x | x <- [1,2,3,4] , y <- [3,4,5,6], x == y ]
[3,4]
```

# 0.5.5 リスト

```haskell
> [1,1+1,3,2,3]
[1,2,3,2,3]
```

---
Haskellのリストの要素には制限があるのでHlistとか使うか、型を用意するかしないといけない。

---

```Haskell
> sum [1,1,0,1,0,1,0]
4
> foldl (+) (-9) [1,1,0,1,0,1,0]
-5
```

Haskellのsumに第2引数はないのでfoldlでかいてみた

# 0.5.10 評価した値がリスト [20,10,15,75] の要素の平均となる式を書け。

```haskell
> (\xs -> sum xs / (fromIntegral . length $ xs)) [20,10,15,75]
30.0
```

求める結果が浮動小数になるように fromIntegralをつかっています。

## リストの結合

`++` で結合可能だけど、効率はいまいち

```
> [1,2,3] ++ [4,5]
[1,2,3,4,5]
> let mylist = [4,8,12]
> mylist ++ [4,5]
[4,8,12,4,5]
> mylist
[4,8,12]
```

```
> [[1,2,3], [4,5,6],[7,8,9]]
```

文字列と数値が混ざったリストはつくれないので数字だけにした。

---

すべてのリストを結合するのはsumではできないのでfoldMapをつかった。

```
> foldMap id [[1,2,3], [4,5,6],[7,8,9]]
[1,2,3,4,5,6,7,8,9]
```
## リストの内包表記

```
> [2*x | x <- [2,1,3,4,5]]
[4,2,6,8,10]
```

```
>  [x*y | x <- [1,2,3] ,y <- [10,20,30]]
[10,20,30,20,40,60,30,60,90]
```

### 課題 0.5.11: リスト [’A’,’B’,’C’] 及び [1,2,3] に対するリスト内包表記で、その値が [文 字, 数字] の全ての可能な組み合わせから成るものを書け。即ち、その値は以下のようなものである。

[[’A’, 1], [’A’, 2], [’A’, 3], [’B’, 1], [’B’, 2],[’B’, 3],
  [’C’, 1], [’C’, 2], [’C’, 3]]

```
> [(x,y) | x <- ['A', 'B', 'C'], y <- [1,2,3]]
[('A',1),('A',2),('A',3),('B',1),('B',2),('B',3),('C',1),('C',2),('C',3)]
```

### 課題 0.5.12: LofL に数字のリストを要素に持つリストを代入したとしよう。このとき、そのリス ト全ての数値全部を足した合計を計算する式を書け。この式は次の形を持ち、内包表記を 1 つ持つ

```
> (\lofl -> sum [sum x| x <- lofl]) [[0.25, 0.75, 0.1], [-1,0], [4,4,4,4]]
16.1
```

### インデックス指定によるリストの要素の取得

```
> let mylist = [1..4]
> mylist !! 0
1
> ["in", "the", "CI"] !! 1
"the"
```

```
> let l = [0,10..90]
> take 5 l
[0,10,20,30,40]
> drop 5 l
[50,60,70,80,90]
> map fst . filter (even . snd) $ zip l [0..]
[0,20,40,60,80]
> map fst . filter (odd . snd) $ zip l [0..]
[10,30,50,70,90]
```

スライスするいい方法がおもいうかばず。

### アンパックによるリストの要素の取得

パターンマッチで代用

```
>  case [4*1, 4*2, 4*3] of [a,b,c] -> print a >> print b >> print c
4
8
12
```

# リストの変更: =の左辺でのインデックス指定

Haskellでは原則リストの変更はできない。
再生成するしかないが効率は微妙なので、ここではおいておく。

# 0.5.6 タプル

```Haskell
> (1, 1+1, 3)
(1, 2, 3)
```

TBD


# 1.2 Pythonにおける複素数

Haskellで複素数をつかうには Data.Complexをimportする。
https://hackage.haskell.org/package/base-4.9.0.0/docs/Data-Complex.html

```Haskell
> import Data.Complex
> 0 :+ 3      -- 3j
> (0 :+ 3) * (0 :+ 3)
(-9.0) :+ 0.0
```

```Haskell
> import Data.Complex
> 1 :+ 3
```

```Haskell
> import Data.Complex
> (1 :+ 3) + (10 :+ 20)
11.0 :+ 23.0
> x = 1 :+ 3
> (x-1) ^ 2
(-9.0) :+ 0.0
```

Haskellの累乗計算の演算子は `^` と `**` がある
`^`が整数要で、`**`が浮動小数点要である

`:+`と`+`の優先順位は同じなので、注意
---

```
> 1 :+ 2 * 3
1 :+ 6
```

```
> 4*(0:+3)^^2
(-36.0) :+ 0.0
```

`0:+`とかくのがすこしめんどくさい
---

実部と虚部のとりだし

```
> realPart (1 :+ 3)
1
> imagePart (1 :+ 3)
3
```
---

型の確認

```
> :t (1:+2)
(1:+2) :: Num a => Complex a
```