はじめに
片山です。
前からやろうやろうと思いつつもなかなか手を出せなかったHaskellに挑戦してみたいと思います。
以前TidalCyclesを紹介しましたが、Haskellベースだったこともあり、いい機会かなと。
Haskell入門
TidalCyclesをやるときにGHCとかCabalは入れてしまったので今回は導入については省きます。
最初のうちはとりあえずインタプリタ(GHCi)でやっていきたいと思います。
$ ghci
GHCi, version 8.0.1: http://www.haskell.org/ghc/ :? for help
Prelude>
進め方としてはLearn You a Haskell for Great Good!のオンライン資料に沿って進めていきたいと思います。
邦訳版の書籍とかも出ているものですが、本家英語版のWebから無料で見られます。
ちなみに筆者は英語がほとんど読めず、なんとなくで進めていく予定なので、Learn You a Haskell for Great Goodの大幅劣化日本語版みたいな記事になるであろうことをご了承下さい(大事な部分の説明とかが抜けてるかもしれません)。
1. Introduction
まずは心構えということでしょうか。
About this tutorial
日本語でおkと思いながら読みました。ほとんど解読できませんでしたが、「Haskellはすごいんだよ!」的なことが書いてある感じがします。
So what's Haskell?
Haskellは純粋関数型言語だよと言っています。遅延評価だし静的型付けだよ的なことが書いてあるような気がします。
What you need to dive in
エディタとコンパイラーがあればいいよ。ghci使うといいよ。的なことが書いてあります。
2. Starting Out
いよいよサンプルコードとかが出てきます。
適当にやっていきたいと思います。
Ready, set, go!
まずは四則演算らしいです。
Prelude> 2 + 5
7
Prelude> 100 - 43
57
Prelude> 4 * 5
20
Prelude> 121 / 11
11.0
Prelude>
こんな感じで普通です。LISPは前置だったのに〜と思って調べてみたらどうやらHaskellも前置出来るみたいです。
Prelude> (+) 4 5
9
Prelude> (-) 100 88
12
Prelude> (*) 2 8
16
Prelude> (/) 93 3
31.0
Prelude>
こんな感じで括弧で括れるよと言っています。5 * -3
みたいなのは動かないから括弧使えとも言ってます。
Prelude> (4 * 6) + 2
26
Prelude> 5 * -3
<interactive>:15:1: error:
Precedence parsing error
cannot mix ‘*’ [infixl 7] and prefix `-' [infixl 6] in the same infix expression
Prelude> 5 * (-3)
-15
試しに前置で書いてみます。
Prelude> (+) ((*) 4 6) 2
26
Prelude>
思った以上にキモいので中置で書くべきなのでしょうか。
次はブール代数です。至って普通な感じです。
Prelude> True && False
False
Prelude> True && True
True
Prelude> True || False
True
Prelude> False || True
True
Prelude> not False
True
Prelude> not (True && True)
False
Prelude> not (True || False)
False
Prelude>
論理演算の次は比較演算です。
Prelude> 333 == 333
True
Prelude> 3 /= 5
True
Prelude>
ノットイコールが!=
ではなくて/=
なのがちょっと珍しい?かもしれません。
あと、型が揃ってないと演算出来ないよと言っています。
Prelude> succ 11
12
Prelude>
いきなり登場した謎の関数succです。見ればわかりますが英語の説明読むの面倒だったのでggったら、案の定「引数を+1して返す」関数みたいです。
教材には載って無かったですが、succを調べてたら「引数を−1して返す」関数もありました。
Prelude> pred 24
23
Prelude>
続いてmin関数とmax関数ですが、これは2つ引数を取ってそれぞれ小さい方、大きい方を返してくれる関数みたいです。
Prelude> min 2 5
2
Prelude> max 1 6
6
Prelude>
div関数なるものが登場しました。整数で割り算してくれるというよく分からない関数らしいです。商が整数になるのがポイント……?
Prelude> div 90 30
3
Prelude> (/) 90 30
3.0
ここで関数は中置出来ますよっていう情報が出てきました。divとかは中置のほうがわかりやすいでしょ?的なことが書いてある気がします。
Prelude> 115 `div` 40
2
Prelude> 12 `max` 13
13
Prelude>
上みたいな感じで``
で囲ってあげると中置出来るみたいです。''
では無いです。
Baby's first functions
これまでは関数を呼び出していたけど、今度は自分で関数を作ってみよう的なことが書いてあるような気がします。
Prelude> testFunc x = x + 100
Prelude> testFunc 5
105
Prelude>
こんな感じで関数作れました。
よく見てみたら、関数作ったらbaby.hsとかって名前で保存して、:l baby
とやれって書いてあったのでやってみます。
Prelude> :quit --ghciを終了するコマンド
Leaving GHCi.
$ emacs baby.hs
babyFunc x = x + 100
$ ghci 2.3.1
GHCi, version 8.0.1: http://www.haskell.org/ghc/ :? for help
Prelude> :l baby
[1 of 1] Compiling Main ( baby.hs, interpreted )
Ok, modules loaded: Main.
*Main> babyFunc 7
107
*Main> babyFunc 5.5
105.5
*Main>
どうやらbaby.hs
をコンパイルして読み込んでくれたみたいです。プロンプトが変化していて、baby.hs
内で定義したbabyFuncが使えるようになっています。
:
に続くコマンドは、教材ページだと|
に見えたり1
に見えたりしましたが、Lの小文字のl
を使います。
次は引数を複数取る関数の定義です。
Prelude> testFunc x y = (max x y)
Prelude> testFunc 1 2
2
Prelude> testFunc x y = x*2 + y*2
Prelude> testFunc 3 4
14
Prelude> testFunc x y z = x + y + z
Prelude> testFunc 1 2 3
6
Prelude>
こんな感じで出来るみたいです。
関数が作れるようになったということで、せっかくなので、唯一の持ちネタであるボディマス計算をやってみたいと思います。
$ emacs bmi.hs
bmi h w = w / (h / 100) ** 2
$ ghci
GHCi, version 8.0.1: http://www.haskell.org/ghc/ :? for help
Prelude> :l bmi
[1 of 1] Compiling Main ( bmi.hs, interpreted )
Ok, modules loaded: Main.
*Main> bmi 178 60
18.93700290367378
*Main>
雑ですがこんな感じですかね。いつも通りですが引数は身長(cm) 体重(kg)
です。Pythonと同じく**
で累乗を計算出来るみたいで便利です。
そういえば最近、長年超えられなかった60kgの壁をやっと突破出来ました。BMIも18.9という今まで出せなかった数値です。ヒョロガリと煽られないようにこの調子でもっと体重を増やしたいです。
終わりに
キリが良いので今回はこの辺で終わりにしようと思います。