Haskellの学習メモ①

Haskellの学習メモ①

関数型言語の考え方を学びたいと思い、すごいHaskellを購入して読んでいますが、読むだけだとすぐに忘れそうなので、ここにメモを残していきます。自分が忘れそうな箇所を箇条書きのように書いていく感じなので、前後に繋がりなどなくて読みにくいかもしれませんがご容赦ください。この記事の対象は1章〜3章までです。

プロジェクトの新規作成

Stackを使って、以下のコマンドを打つと新規プロジェクトが作成できる。

stack new myproj # `myproj` は任意のプロジェクト名

ビルド

stack build

実行

stack exec myproj-exe # `myproj` は任意のプロジェクト名

リスト内包表記

リストのフィルタリング、変換、組み合わせを行う方法。数学に出てくる集合の内包的記法に近い。

let result = [x*2 | x <- [1..10]]
print result
-- 結果:[2,4,6,8,10,12,14,16,18,20]

x <- [1..10] は[1..10]から取り出した各要素の値をxが受け取るという意味。別の表現だと[1..10]の各要素をxに束縛している。

パターンマッチ

関数の中の処理を場合分けするのに使う。パターンは上から下の順に評価され、パターンに合致すると残りのパターンは無視される。

lucky :: Int -> String
lucky 7 = "lucky number"
lucky x = "not lucky number"

呼び出し側のコードは以下。

let test = lucky 7
print test
-- 結果:"lucky number"

ガード

パターンマッチと同様に場合分けする時に使用する。使い分けとしては、引数の構造で場合分けする時はパターンを使い、引数の値が満たす性質で場合分けするときはガードを使うようです。(上で書いたパターンの例は、値の性質な気はするが)。if文との使い分けは、複数の条件がある場合はガードの方がif文よりも可読性が高いとのこと。

bmiTell :: Double -> String
bmiTell bmi
  | bmi <= 18.5 = "slim"
  | bmi <= 25.0 = "normal"
  | bmi <= 30.0 = "fat"
  | otherwise = "..."

呼び出し側のコードは以下。

let test = bmiTell 18
print test
-- 結果:"slim"

where

計算結果を格納し、関数内でのみ使用可能な変数。

bmiTell :: Double -> Double -> String
bmiTell weight height
  | bmi <= 18.5 = "slim"
  | bmi <= 25.0 = "normal"
  | bmi <= 30.0 = "fat"
  | otherwise = "..."
  where
    bmi = weight / height ^ 2

let式

whrereは関数の後ろで変数を束縛するのに対し、let式はどこでも変数を束縛できる&let自身も式になる。

cylinder :: Double -> Double -> Double
cylinder r h =
  let sideArea = 2 * pi * r * h
      topArea = pi * r ^ 2
   in sideArea + 2 * topArea