コミュ障だから明日が僕らをよんだって返事もろくにしなかった

何かを創る人に憧れたからブログをはじめたんだと思うよ

トライハスケル!

イエスハスケルハスケルハスケル

Haskelのオンライン実行環境見つけた。こういうのあったんですね。全然知りませんでした。
tryhaskell.org


別に今手を出す必要はないけど最近関数型言語かじりつつあるし、手を出してもいいかなと思ってやってみることにします。helpって打つと簡易チュートリアルはじまるようなのでちょっと触ってみる。

Type Haskell expressions in here.
λ help

helpと入力することでチュートリアル開始します。


λ 5+7
12
:: Num a => a

まずは簡単な四則演算。:: 型で型を示すようです。


λ "chris"
"chris"
:: [Char]

名前を入力してみましょう的話。文字列って [Char] 型なんですね、String型ないのか。

λ [42,13,22]
[42,13,22]
:: Num t => [t]

リストの作り方について

λ sort [42,13,22]
[13,22,42]
:: (Num a, Ord a) => [a]

sortの使い方について

λ sort "chris"
"chirs"
:: [Char]

文字列でもsortできるとのこと

λ (28, "chirs")
(28,"chirs")
:: Num t => (t, [Char])

タプルの使い方について、こちらは型が異なるときに使用

λ (1,"hats",23/35)
(1,"hats",0.6571428571428571)
:: (Fractional t1, Num t) => (t, [Char], t1)
λ ("Shaggy","Daphnie","Velma")
("Shaggy","Daphnie","Velma")
:: ([Char], [Char], [Char])
λ (28,"chirs")
(28,"chirs")
:: Num t => (t, [Char])
λ fst (28,"chirs")
28
:: Num a => a
λ  

要素の取り出しにはfstなんてものがあるらしい。2個目ならsnd、3個目ならば牙をむく……trdはエラーになる。なんなのこれ。

λ let x = 4 in  x * x
16
:: Num a => a

変数を "束縛" します。束縛ってなんやねん。とりあえずスコープ範囲を限定するときにlet使うって覚えることにする。


λ let villain = (28,"chirs") in fst villain
28
:: Num a => a

上のやつの使用例その2。

λ 'a' : []
"a"
:: [Char]

リストをつくろう!


λ 'a' : 'b' : [] == ['a','b']
True
:: Bool

リストになっているか確認してみよう!'a' : 'b' : []で右のやつになるんですね。


λ ['a','b','c'] == "abc"
True
:: Bool

念押しのもう一回!

λ map (+1) [1..5]
[2,3,4,5,6]
:: (Enum b, Num b) => [b]

λ map (*99) [1..10]
[99,198,297,396,495,594,693,792,891,990]
:: (Enum b, Num b) => [b]
λ map (/5) [13,24,52,42]
[2.6,4.8,10.4,8.4]
:: Fractional b => [b]
λ filter (>5) [62,3,25,7,1,9]
[62,25,7,9]
:: (Num a, Ord a) => [a]

mapの使い方について。途中filterが入っていたりするけどもそこは気にしてはいけない。このあたりRubyやなんかのイテレータ使って遊んでるとすっきり頭に入る。


λ (1,"George")
(1,"George")
:: Num t => (t, [Char])

λ 1:[2,3]
[1,2,3]
:: Num a => [a]

タプルとリストについて。:を使うことでリストを結合できるらしい


λ let square x = x * x in square 3
9
:: Num a => a
λ let add1 x = x + 1 in add1 5
6
:: Num a => a
λ let second x = snd x in second (3,4)
4
:: Num b => b
λ let square x = x * x in map square [1..10]
[1,4,9,16,25,36,49,64,81,100]
:: (Enum b, Num b) => [b]

正方形の面積、1を加える計算、二つの値の後ろの数値を取る、正方形の面積map版などなどに応用できるとのこと。

λ let add1 x = x + 1 in map add1 [1,5,7]
[2,6,8]
:: Num b => [b]
λ let take5s = filter (==5) in take5s [1,5,2,5,3,5]
[5,5,5]
:: (Eq a, Num a) => [a]
λ let take5s = filter (==5) in map take5s [[1,5],[5],[1,1]]
[[5],[5],[]]
:: (Eq a, Num a) => [[a]]

λ toUpper 'a'
'A'
:: Char

mapを更に応用してみるの巻。あと文字を大文字に変換する方法。

λ map toUpper "Chris"
"CHRIS"
:: [Char]

文字でもmapを組み合わせればこのようにできるとのことです。

λ let (a,b) = (10,12) in a * 2
20
:: Num a => a

パターンマッチについてみていきましょうという話。条件分岐的なものに使うとシンプルに書けるらしい。


λ let (a:b:c:[]) = "xyz" in a
'x'
:: Char

確認用のもう一回


λ let (a:_:_:_) = "xyz" in a
'x'
:: Char
λ let (a:_) = "xyz" in a
'x'
:: Char

_で他の値を無視できます。よくわかんないけどGo言語のアンダースコア変数みたいなノリでいいんすかね?


λ let (_,(a:_)) = (10,"abc") in a
'a'
:: Char

'a' を取り出してみようてきなやつ。

λ let _:_:c:_ = "abcd" in c
'c'
:: Char
λ let [a,b,c] = "cat" in (a,b,c)
('c','a','t')
:: (Char, Char, Char)

λ let abc@(a,b,c) = (10,20,30) in (abc,a,b,c)
((10,20,30),10,20,30)
:: (Num t, Num t1, Num t2) => ((t, t1, t2), t, t1, t2)

パターンマッチ応用編。全体@パターンで色々アクセスできるようになるとのこと。


やってみたら、普通に文法確認でした。まあ文法確認用記事作ってないしまあいいこれでもいいか。5分で理解するチュートリアルみたいなこと書いてあった気がしたけどなんだかんだ調べていたら小一時間かけてやってしまった。まあ、まだ今の僕にはHaskellで『モナド完全に理解した』とイキルにははやすぎたみたいです。ダニング=クルーガー効果的なやつでいえばもうそろそろ「完全に理解した」とかイキれると思うんですけど、今のところぜんぜんわからん。


参考資料
Chapters - Learn You a Haskell for Great Good!