クリーム色の背景、色付き表示、高コントラスト、大きな文字のほうが読みやすいですか?配色と文字を選ぶと、すべてのページに一度で反映されます。

無料レッスン

Haskellの関数と型

このレッスンのあとで: Haskell の短い関数と、その型の宣言を読むことができる。

65分のレッスンコマンド6件Haskell ラボ:関数と型で学ぶ関数型プログラミングをブラウザーで

値を受け取り、値を返すだけ

関数型プログラミングは、プログラムを「値を受け取って値を返す関数」の組み合わせで書く方法です。Haskell(ハスケル)では、どの関数にも型がつき、型を読めば何を渡せるかが分かります。

店のレジで、価格から税込みの値段を出す計算を考えます。入れた価格が同じなら、いつ計算しても同じ値段が出ます。この性質を、そのまま言語の決まりにしたのが関数型です。

このレッスンのゴール

メモ

Haskell の短い関数と、その型の宣言を読むことができる。

キーワード

ことばいみれい
純粋関数同じ入力なら必ず同じ出力を返す関数
型値の種類Int、String、Bool
型シグネチャ関数が受け取る型と返す型の宣言Int -> Int
関数合成2つの関数をつなぎ、1つの関数にすること
式評価すると値になる、ひとまとまりの書き方

学生が入力するセルは、このプレビューでは空白です。

純粋な関数は入力だけで決まる

純粋関数は、受け取った値だけから結果を決めます。画面に書いたり、外の変数を書きかえたりしません。同じ入力には、いつでも同じ出力です。

そのため、関数を1つずつ取り出して試せます。外の状態を気にしなくてよいので、組み合わせてもこわれにくいのが利点です。

例: 3つの小さな関数

コード: haskell
-- 例です。-- から後ろはコメントです。
square :: Int -> Int
square n = n * n

greet :: String -> String
greet name = "Hello, " ++ name ++ "!"

isEven :: Int -> Bool
isEven n = mod n 2 == 0

ラボの端末で Haskell を動かす

次のコマンドは、ラボの端末に打ちこむ1行です。runghc はファイルを動かし、ghc -e は式を1つ評価して結果を出します。コンパイラが出す文字は、すべて英語です。

Basics.hs を書きかえていなければ、上の3つの関数と、それを呼ぶ main が入っています。

Basics.hs を動かす

コマンド
docker exec haskell runghc Basics.hs

ここでは表示のみで、実行されません。無料アカウントを作成すると、実行ボタンで自分のラボのターミナルに入力できます。

その場で関数を作って呼ぶ

コマンド
docker exec haskell ghc -e 'let double :: Int -> Int; double x = x * 2 in double 21'

ここでは表示のみで、実行されません。無料アカウントを作成すると、実行ボタンで自分のラボのターミナルに入力できます。

型シグネチャは関数の契約である

square :: Int -> Int は、「square は Int を1つ受け取り、Int を返す」と読みます。:: の右が型で、矢印の左が入力、最後が出力です。

型を先に読めば、本体を読まなくても使い方が分かります。まちがった型の値を渡すと、動かす前にエラーで止まります。

例: 型シグネチャの読み方

関数型シグネチャ読み方
squareInt -> Int整数を受け取り、整数を返す
greetString -> String文字列を受け取り、文字列を返す
isEvenInt -> Bool整数を受け取り、真偽を返す
notBool -> Bool真偽を受け取り、真偽を返す

学生が入力するセルは、このプレビューでは空白です。

not の型を調べる

コマンド
docker exec haskell ghc -e ':t not'

ここでは表示のみで、実行されません。無料アカウントを作成すると、実行ボタンで自分のラボのターミナルに入力できます。

型のまちがいを起こす

コマンド
docker exec haskell ghc -e 'not 5'

ここでは表示のみで、実行されません。無料アカウントを作成すると、実行ボタンで自分のラボのターミナルに入力できます。

よくある間違い

注意

「Haskell でも max(3, 7) のようにかっこで呼ぶ」と考える人が多くいます。Haskell は関数名のあとに、空白で区切って値を並べ、max 3 7 と書きます。かっこは、まとまりを作るときだけ使います。

関数合成で2つの関数をつなぐ

関数合成は、ピリオド1つで2つの関数をつなぐ書き方です。length . words は、まず words で文を単語に分け、次に length で数えます。

右の関数が先に働き、その結果が左の関数に渡ります。型が合っていれば、つなぎ目の型も合います。

単語の数を数える

コマンド
docker exec haskell ghc -e '(length . words) "one two three"'

ここでは表示のみで、実行されません。無料アカウントを作成すると、実行ボタンで自分のラボのターミナルに入力できます。

合成した関数の型を調べる

コマンド
docker exec haskell ghc -e ':t length . words'

ここでは表示のみで、実行されません。無料アカウントを作成すると、実行ボタンで自分のラボのターミナルに入力できます。

Python で関数を値として渡す

コード: python
# 関数も、数や文字列と同じように、別の関数に渡せます。
def double(n):
    return n * 2


def add_tax(price):
    return price * 110 // 100


def apply_twice(f, x):
    return f(f(x))


print(apply_twice(double, 5))
print(apply_twice(add_tax, 1000))
# apply_twice の中の f(f(x)) を f(x) に変えて、もう一度実行してみましょう。

このラボとソースについて: Haskell ラボ:関数と型で学ぶ関数型プログラミングをブラウザーで

授業で使いますか?このモジュールを学生に割り当てると、教員用ガイド、自動採点つきの課題、学生ごとのラボを使えます。