Haskellチートシート(翻訳)

http://cheatsheet.codeslower.com/CheatSheet.pdf の翻訳です。
日本語訳版のファイルが無くなっているようなので。
誤字誤訳その他問題があればコメント、編集リクエストください。
また、直訳な部分も多いので良い訳がある場合もコメント、編集リクエストください。

# Haskell Cheat Sheet
このチートシートはHaskellの基本的な要素である構文、キーワード、その他の要素を記しています。また、実行可能なHaskellファイル、印刷可能なドキュメントです。お好きなインタプリタでソースを読み込んでサンプルコードを動かしてください。

# 基本構文

## コメント
単一行コメントは`--`で始まり、行末までがコメントになります。複数行コメントは`{-`から`-}`までです。コメントはネストすることができます。
HaskellコードのドキュメントシステムであるHaddockのための関数定義のコメントは`{- |`で始まり、その型へのコメントは`-- ^`です。(訳注:より良い訳求む)

## 予約語
Haskellで以下のワードは予約されています。変数か関数の名前で使うと構文エラーになります。

* case
* class
* data
* deriving
* do
* else
* if
* import
* in
* infix
* infixl
* infixr
* instance
* let
* of
* module
* newtype
* then
* type
* where

## 文字列
* `"abc"` - ユニコード文字列で`['a', 'b', 'c']`の糖衣です。
* `'a'` - 単一文字。

### 複数行文字列
通常文字列が改行文字を含むと構文エラーになります。従ってこれは構文エラーです。

```hs
string1 = "My long
string."
```

バックスラッシュ('\')は改行を"エスケープ"できます。

```hs
string1 = "My long \
\string."
```

バックスラッシュの間の部分は無視されます。文字列*中*の改行は明示的に表されます。

```hs
string2 = "My long \n\
\string."
```

従って、`string1`は

```
My long string.
```

そして`string2`は

```
My long
string.
```

と評価されます。

### エスケープコード
以下のエスケープコードは文字と文字列の中で使うことができます。
* `\n`, `\r`, `\f`など - 改行、キャリッジリターン、フォームフィードなどの標準的なコードがサポートされています。
* `\72`, `\x48`, `\o110` - それぞれ10進数、16進数、8進数表記の文字です。
* `\&` - 数字のエスケープコードが数字リテラルと隣り合うのを許可する"null"のエスケープ文字。 例えば`\x2C4`は(Unicodeにおける)∧ですが、`\x2C\&4`は`,4`です。この繋がりは文字リテラルで使うことができません。

## 数字
* 1 - 整数か浮動小数点数
* 1.0, 1e10 - 浮動小数点数
* 0o1, 001 - 8進数
* 0x1, 0X1 - 16進数
* -1 - 負数。マイナス記号("-")を数字と分けることはできません

## 列挙
* [1..100] - 数字のリスト - 1, 2, ..., 100
* [100..] - 数字の無限リスト - 100, 101, 102, ...,
* [110..100] - 空リストですが、[110, 109 .. 100]は110から100のリストになります
* [0, -1 ..] - 負数のリスト
* [-110..-100] - 構文エラー。負数には[-110.. -100]が要求されます。
* [1, 3..99], [-1, 3..99] - 1から2ごとの99までのリスト、-1から4ごとの99までのリスト

実はEnumクラスのどんな値でも使えます。

* ['a' .. 'z'] - 文字のリスト - a, b, .., z
* ['z', 'y' .. 'a'] - z, y, x, .., a
* [1.0, 1.5 .. 2] - [1.0, 1.5, 2.0]
* [UppercaseLetter ..] - GeneralCategory値(Data.Charから)のリスト

## リストとタプル
* [] - 空リスト
* [1, 2, 3] - 3つの数字のリスト
* 1 : 2 : 3 : [] - "cons"(:)と"nil"([])を使ったリストの別記法
* "abc" - 三つの文字のリスト(文字列はリスト)
* 'a' : 'b' : 'c' : [] - 文字のリスト("abc"と同じ)
* (1, "a") - 数字と文字列の2つの要素のタプル
* (head, tail, 3, 'a') - 2つの関数と数字と文字の4要素のタプル

## レイアウトルール、波括弧とセミコロン
HaskellはCのように波括弧とセミコロンを使って書くことができます。しかし、そうする人はいません。代わりにスペースがスコープを表す"レイアウト"ルールを使います。一般的なルールは常にインデントすることです。コンパイラがエラーを出す時に、よりインデントしてください。(訳注:より良い訳求む)

### 波括弧とセミコロン
セミコロンは式の終了、波括弧はスコープを表します。これらはいくつかのキーワード、where, let, do, ofの後に使えます。これらは関数本体の定義では使えません。例えば以下はコンパイルされません。

```hs
square2 x = { x * x; }
```

しかし、これはうまくいきます。

```hs
square2 x = result
  where { result = x * x; }
```

### 関数定義
where節がなければ、関数本体は関数の名前から最低でも1スペースはインデントしてください。

```hs
square x =
  x * x
```

where節は関数名から最低でも1スペース、関数本体はwhere節から最低でも1スペースはインデントしてください。

```hs
square x =
    x2
  where x2 =
    x * x
```

### Let
letの本体はletの最初の定義から最低でも1スペースインデントしてください。もしletが自身の行に現れるならば、定義部はletよりインデントされていなければなりません。

```hs
square x =
  let x2 =
        x * x
  in x2
```

上から分かるように、inキーワードはletと同じ列でなければなりません。最後に、複数の定義がある時に全ての識別子は同じ列になくてはなりません。(訳注:より良い訳求む)

# 宣言など
以下のセクションでは関数宣言のルール、リストの理解、言語の他のことについて詳説します。

## 関数宣言
関数は関数名、引数、イコール記号の宣言によって定義されます。

```hs
square x = x * x
```

*全ての*関数は小文字か"_"で始まる必要があります。そうでなければ構文エラーとなります。

### パターンマッチング
関数の複数節は引数の値のパターンマッチングによって定義することができます。以下は4つの分けられたケースを持つagree関数です。

```hs
-- 文字列の"y"が与えられた時にマッチ
agree1 "y" = "Great!"
-- 文字列の"n"が与えられた時にマッチ
agree1 "n" = "Too bad."
-- 'y'で始まる文字列が与えられた時にマッチ
agree1 ('y':_) = "YAHOO!"
-- 他のどんな値が与えられた時にもマッチ
agree1 _ = "SO SAD."
```

'_'文字はワイルドカードでどんな値にもマッチします。
パターンマッチングは入れ子の値にも使えます。

このデータ宣言があるとして、

```hs
data Bar = Bil (Maybe Int) | Baz
```

Maybeの定義は7ページを見てください。
Bilがある時入れ子になったMaybeをマッチさせることができます。

```hs
f (Bil (Just _)) = ...
f (Bil Nothing) = ...
f Baz = ...
```

パターンマッチングは変数への代入もできます。例えばこの関数は与えられた文字列が空かどうかを定めます。もし空でなければstrに束縛された値を小文字に変更します。

```hs
toLowerStr [] = []
toLowerStr str = map toLower str
```

上のstrはどんなものにもマッチする点で同じです。唯一の違いはマッチした値に名前が与えられるかどうかです。

### n + kパターン
この(しばしば論争になります)パターンマッチングは特定の数字の表現のマッチを簡単にします。アイデアはベースとなるケース("n"の割り当て)にマッチのための定数を定義し、他のマッチ("k"の割り当て)をベースクラスへの添加として定義します。以下はいくぶん非効率な偶数かどうかの試行方法です。

```hs
isEven 0 = True
isEven 1 = False
isEven (n + 2) = isEven n
```

### 引数捕捉(asパターン)
引数の捕捉は追加の変数の宣言なしでの値のパターンマッチング、**かつ**、その使用に便利です。マッチするパターンと値を束縛する変数の間で'@'シンボルを使ってください。この機能は以下で表示するためのリストの先頭を`l`に、長さを計算するためにリスト全体を`ls`に束縛することに使われています。

```hs
len ls@(l:_) = "List starts with " ++
  show l ++ " and is " ++
  show (length ls) ++ " items long."
len [] = "List is empty!"
```

### ガード
真偽関数は"ガード"としてパターンマッチングに伴って関数の定義に使うことができます。パターンマッチングなしの例です。

```hs
which n
  | n == 0 = "zero!"
  | even n = "even!"
  | otherwise = "odd!"
```

otherwiseは常にTrueと評価され、"デフォルト"の場合を明示するのに使われます。

ガードはパターンを伴って使うこともできます。以下は文字列の最初の文字が大文字か小文字か定める関数です。

```hs
what [] = "empty string!"
what (c:_)
  | isUpper c = "uper case!"
  | isLower c = "lower case!"
  | otherwise = "not a letter!"
```

### マッチングとガードの順
パターンマッチングは上から下へ進みます。同様に、ガード節も上から下へ試されます。例えばこれらの関数はどれも面白くないです。

```hs
allEmpty _ = False
allEmpty [] = True

alwaysEven n
  | otherwise = False
  | n `div` 2 == 0 = True
```

### レコード構文
普通、パターンマッチングはマッチした値の中で引数の位置に基づいて行われます。しかしレコード構文で宣言された型はレコードの名前に基づいてマッチすることができます。この型を与えます。

```hs
data Color = C { red
  , green
  , blue :: Int }
```

greenだけでマッチできます。

```hs
isGreenZero (C { green = 0 }) = True
isGreenZero _ = False
```

引数の捕捉はこの構文でも可能ですが、不恰好です。上のものに続けて、Pixel型と0ではない緑を全て黒に置き換える関数を定義します。

```hs
data Pixel = P Color

-- 緑が0なら変更しない
setGreen (P col@(C { green = 0 })) = P col
setGreen _ = P (C 0 0 0)
```

### 遅延パターン
この構文は(irrefutable patterns)としても知られており、常に成功するパターンマッチです。エラーを起こすかもしれないマッチした値を使おうとするのでなければ、これはこのパターンを使うどんな節にも成功するということです(訳注:より良い訳求む)。これは特定の値の*型*が取られない、たとえ値がない時に一般的に便利です。
例えば、デフォルト値のためのクラスを定義します。

```hs
class Def a where
  defValue :: a -> a
```

`defValue` に正しい型を与えて、その型のデフォルト値を返すという考えです。基本的な型のインスタンス定義は簡単です。

```hs
instance Def Bool where
  defValue _ = False

instance Def Char where
  defValue _ = ' '
```

`Maybe` はもう少しトリッキーです、なぜなら型のデフォルト値が欲しいからです。しかしコンストラクタは`Nothing`かもしれません。以下の定義は動きますが、`Nothing`が渡された時に`Nothing`を得るので最適ではありません。

```hs
instance Def a => Def (Maybe a) where
  defValue (Just x) = Just (defValue x)
  defValue Nothing = Nothing
```

むしろ代わりにJust (*デフォルト値*)を返して欲しいのです。ここで遅延パターンの出番です - たとえ`Nothing`が与えられても`Just x`にマッチし、デフォルト値を使うと決め込むのです。

```hs
instance Def a => Def (Maybe a) where
  defValue ~(Just x) = Just (defValue x)
```

`x` 値が実際に評価されない限り、安全です。どの基本的な型も`x`を見る必要がありません(`_`のマッチを見てください)。よって上手くいきます。
以上のことの1つの小さな問題は`Nothing`コンストラクタを使う時にインタプリタやコードに型注釈を与えないといけないことです。`Nothing`は`Maybe a`型を持っていますが、他の十分な情報がなければHaskellに`a`は何か教えないといけません。デフォルト値のいくつかの例です。

```hs
-- Return "Just False"
defMB = defValue (Nothing :: Maybe Bool)
-- Return "Just ' '"
defMC = defValue (Nothing :: Maybe Char)
```

## リスト内包表記
リスト内包表記は4つのタイプの要素から成ります。ジェネレータとガードとローカル束縛とターゲットです。リスト内包表記は与えられたジェネレータとガードに基づいたターゲットの値のリストを作ります。この内包表記は全ての平方数を生成します。

```hs
squares = [x * x | x <- [1..]]
```

x <- [1..]は全てのIntegerの値のリストを生成し、xに一つ一つ入れます。x * xは自身をかけることによってリストの要素を作ります。

ガードは除外される要素をもたらします。以下は与えられた数の約数(自身を除く)がどのように計算できるかを示します。dがガードとターゲットでどのように使われているか気を付けてください。

```hs
divisors n =
  [d | d <- [1..(n `div` 2)]
     , n `mod` d == 0]
```

ローカル束縛は生成された式や後続のジェネレータとガードで使われる新しい定義を与えます。以下は`z`が`a`と`b`の小さい方を表すのに使われるものです。

```hs
strange = [(a,z) | a <-[1..3]
                 , b <-[1..3]
                 , c <- [1..3]
                 , let z = min a b
                 , z < c ]
```

内包表記は数字に限定されいません。どんなリストでもできます。全ての大文字の文字が生成でき、

```hs
ups =
  [c | c <- [minBound..maxBound]
     , isUpper c]
```

あるいはリスト`word`から特定の`br`の全ての位置を見つけることができます(0からインデックスされる)。

```hs
idxs word br =
  [i | (i, c) <- zip [0..] word
     , c == br]
```

リスト内包表記特有の機能はパターンマッチングの失敗がエラーを起こさないことです。結果のリストから除外されるだけです。

## 演算子
Haskellでは厳密な"演算子"が予めほとんど定義されていません(予め定義されたほとんどは実は構文です。例えば"=")。代わりに演算子は二つの引数を取るただの関数で、特別な構文のサポートされます。そのように使われる演算子は括弧を使うことで前置関数として使われます。

```hs
3 + 4 == (+) 3 4
```

新しい演算子を定義するには普通の関数として定義しますが、演算子は二つの引数の間に現れます。これは2つの文字列の間にコンマを入れて余計なスペースが含まれないようにするものです。

```hs
first ## last =
  let trim s = dropWhile isSpace
        (reverse (dropWhile isSpace
          (reverse s)))
  in trim last ++ ", " ++ trim first

> " Haskell " ## " Curry "
Curry, Haskell
```

もちろんこの形でも完全なパターンマッチング、ガード、その他は有効です。型のシグネチャは少し違いますが。演算子の名前は括弧の中になくてはなりません。

```hs
(##) :: String -> String -> String
```

演算子の定義に使える記号は

`# $ % & * + . / < = > ? @ \ ^ | - ~`

です。
しかし、再定義できない"演算子"がいくつかあります。`<-` `->` `=`です。最後の`=`はそれ自身によって再定義することはできませんが、複数文字の演算子の一部としては使うことができます。"bind"関数、`>>=`は例の1つです。

### 優先度と結合性
優先度と結合性は合わせて**fixity**と呼ばれ、その演算子は_infix_、_infixr_、_infixl_キーワードを通して定められます。これらはトップレベル関数、局所レベル定義両方に適用されます。構文は

{_infix_ | _infixr_ | _infixl_} _優先度_ _演算子_

で、_優先度_は0から9です。_演算子_は実は引数を二つ取るあらゆる関数(例えばバイナリ演算子)です。演算子が左か右の結合性であるかは_infixl_なのか_infixr_なのかによってそれぞれ明示されます。_infix_は結合性を持たないことを宣言します。

優先度と結合性は算術的機能のルールの多くを期待します。例えば加算と乗算の優先度を少し更新を考えてみます。

```hs
infixl 8 `plus1`
plus1 a b = a + b
infixl 7 `mult1`
mult1 a b = a * b
```

結果には驚きます。

```hs
> 2 + 3 * 5
17
> 2 `plus1` 3 `mult1` 5
25
```

優先度の逆転は他にも面白い効果を持ちます。割り算を再定義します。

```hs
infixr 7 `div1`
div1 a b = a / b
```

興味深い結果を得ます。

```hs
> 20 / 2 / 2
5.0
> 20 `div1` 2 `div1` 2
20.0
```

## カリー化
Haskellでは関数は引数の全てを一度に与える必要はありません。例えば、testに依存する文字列のある要素だけを変換する`convertOnly`関数を考えてみます。

```hs
convertOnly test change str =
  map (\c -> if test c
              then change c
              else c) str
```

`convertOnly`を使って、特定の文字を数字に変換する`l33t`関数を書くことができます。

```hs
l33t = convertOnly isL33t toL33t
  where
    isL33t 'o' = True
    isL33t 'a' = True
    -- etc.
    isL33t _ = False
    toL33t 'o' = '0'
    toL33t 'a' = '4'
    -- etc.
    toL33t c = c
```

`l33t`は明示的な引数を取らないことに気付いてください。また、`convertOnly`の最後の引数は与えられていません。しかし、`l33t`の型シグネチャは全てを物語っています。

```hs
l33t :: String -> String
```

すなわち、`l33t`は文字列を受け取って文字列を作ります。`l33t`は常に文字列を受け取り文字列を作る関数という意味で'不変的'です。`l33t`は`convertOnly`の'カリー化'された形で、それは3つの引数の内2つだけを与えられたものです。
更に続けて、大文字だけを変えたい関数を書きたいとします。`isUpper`をtestに適用するのは分かっていることですが、変換方法は明示したくありません。そんな関数はこう書けます。

```hs
convertUpper = convertOnly isUpper
```

その型シグネチャは

```hs
convertUpper :: (Char -> Char)
  -> String -> String
```

です。
すなわち、`convertUpper`は2つの引数を取ります。最初は個々の文字を変換する変換関数、二つ目は変換される文字列です。

複数の引数を取るどんな関数のカリー化された形を作ることができます(原文”A curried form of any function which takes multiple arguments can be created”)。これの考え方の1つの方法は関数のシグネチャの中の矢印は1つ以上の引数を与えることによって作ることのできる新しい関数を表しています。

### セクション記法
演算子は関数で、他の関数と同じようにカリー化することができます。例えば"+"のカリー化されたバージョンはこう書けます。

```hs
add10 = (+) 10
```

しかし、これは不恰好で読むのが難しいです。"セクション記法"は括弧を使って演算子をカリー化します。セクション記法を使った`add10`はこれです。

```hs
add10 = (10 +)
```

与えられた引数は右か左にあり、これは与えるべき位置を示します。これは連結等の演算子に重要です。

```hs
onLeft str = (++ str)
onRight str = (str ++)
```

これはかなり違った結果を作ります。

```hs
> onLeft "foo" "bar"
"barfoo"
> onRight "foo" "bar"
"foobar"
```

## 値の更新とレコード構文
Haskellは純粋な言語で、それ自身として可変な状態を持ちません。すなわち、一度値がセットされると変更されません。"更新"は"変更された"フィールドの新しい値による、正にコピー作業です。例えば先に定義した`Color`型を使って、より簡単に`green`にゼロをセットする関数を書けます。

```hs
noGreen1 (C r _ b) = C r 0 b
```

これは少し冗長で、レコード構文を使って書き直すことができます。この種の"更新"は明示されたフィールドに値をセットし、残りをコピーするだけです。

```hs
noGreen2 c = c { green = 0 }
```

ここでは、`c`で`Color`の値を捕捉して新しい`Color`の値を返しています。その値は`c`の`red`と`blue`と同じ値を持つことになり、`green`部分は0です。これは`red`フィールドと等しい値をセットするためにパターンマッチングと組み合わせることができます。

```hs
makeGray c@(C { red = r }) =
  c { green = r, blue = r}
```

`Color`の値を手に入れるための引数の捕捉("c@")と内側の`red`フィールドを手に入れるためのレコード構文("C { red = r}")によるパターンマッチングを使わなくてはならないことに注意してください。

## 匿名関数
匿名関数(_ラムダ式_や短く_ラムダ_)は名前のない関数です。これらはいつでもこのように定義できます。

```hs
\c -> (c, c)
```

そしてそれは引数をとって両方の位置に引数を持つタプルを返します。名前の必要ない単純な関数に便利です。以下は文字列が大文字と小文字とスペースが混ざったものだけから成っているかどうか決める関数です。

```hs
mixedCase str =
  all (\c -> isSpace c ||
             isLower c ||
             isUpper c) str
```

もちろんラムダ式は関数から返すこともできます。この古典(原文"This classic")は元より与えられた引数と乗算する関数を返します。

```hs
multBy n = \m -> n * m
```

例えば

```hs
> let mult10 = multBy 10
> mult10 10
100
```

## 型シグネチャ
Haskellは尽く型推論をします。これはほとんどの場合型を書かなくてもよいということです。しかし、型シグネチャは依然として少なくとも2つの理由で便利です。

_ドキュメンテーション_ - 例えコンパイラが関数の型を分かっても、他のプログラマやあなた自身さえも分からないかもしれません。トップレベルの全ての関数に型シグネチャを書くことはとても良い形式と考えられています。

_特化_ - 型クラスは関数のオーバーロードをもたらします。例えば数字のリストの全てをマイナスする関数は

```hs
negateAll :: Num a => [a] -> [a]
```

というシグネチャを持ちますが、能率や他の理由のために`Int`型のみ許可したいならば、

```hs
negateAll :: [Int] -> [Int]
```

という型シグネチャによって達成できます。

型シグネチャはトップレベル関数とネストした`let`、`where`定義に現れます。一般にこれはドキュメンテーションに便利ですが、いくつかの場合で多相を防ぐのに必要です。型シグネチャは最初に型付けされるものの名前に続いて、`::`が続き、型が続きます。この例はすでに上で述べました。

型シグネチャは実装の直上に現れる必要はありません。それを含むモジュールのどこでも明示することができます(たとえそれより下でも!)。同じシグネチャを持つ複数の関数は一緒に定義できます。

```hs
pos, neg :: Int -> Int

...

pos x | x < 0 = negate x
      | otherwise = x

neg y | y > 0 = negate y
      | otherwise = y
```

### 型注釈
Haskellでは時々型が何を意味しているのか決定できません。この古典的な実演は"`show . read`"問題です。

```hs
canParseInt x = show (read x)
```

Haskellは`read x`の型を知らないのでこの関数をコンパイルすることはできません。注釈を通して型を制限しなければなりません。

```hs
canParseInt x = show (read x :: Int)
```

注釈は型シグネチャと同じ構文を持ちますが、どんな式を装飾しても良いです。上の注釈は`read x`という式に対するもので、`x`へのものではありません。関数適用(例えば`read x`)だけは注釈よりも優先的に結合します。もしそうでなければ、上は`(read x) :: Int`と書かなければならなかったでしょう。

## Unit
`()` - "unit"型と"unit"値。値と型は不要な情報を表します。

# キーワード
Haskellのキーワードを以下にアルファベット順で列挙しました。

## Case

`case`はC#やJavaの `switch`文と似ていますが、パターンにマッチすることができ、値の形が検査されます。シンプルなデータを考えます。

```hs
data Choices = First String | Second |
  Third | Fourth
-- deriving (Show, Eq)
```

`case`はどのchoiseが与えられたか決めるのに使うことができます。

```hs
whichChoice ch =
  case ch of
    First _ -> "1st!"
    Second -> "2nd!"
    _ -> "Something else."
```

関数定義のパターンマッチングと同様に'`_`'トークンはどんな値にもマッチするワイルドカードです。

### 入れ子と捕捉
入れ子のマッチングと束縛は許可されています。例えばこのMaybe型の定義

```hs
data Maybe a = Just a | Nothing
```

`Maybe`によって入れ子になったマッチを使ってchoiceが与えられたかどうか決定することができます。

```hs
anyChoice1 ch =
  case ch of
    Nothing -> "No choice!"
    Just (First _) -> "First!"
    Just Second -> "Second!"
    _ -> "Something else."
```

束縛はマッチした値の操作にも使われます。

```hs
anyChoice2 ch =
  case ch of
    Nothing -> "No choice!"
    Just score@(First "gold") ->
      "First with gold!"
    Just score@(First _) ->
      "First with something else: "
      ++ show score
    _ -> "Not first."
```

### マッチの順序
マッチングは上から下へ進みます。もし`anyChoice1`が以下のように並び替えられると、常に最初のパターンが成功します。

```hs
anyChoice3 ch =
  _ -> "Something else."
  Nothing -> "No choice!"
  Just (First _) -> "First!"
  Just Second -> "Second!"
```

### ガード
ガード、あるいは条件付きマッチングは関数定義のような時に使われます。ただ一つの違いは`=`の代わりに`->`を使うことです。これは大文字小文字を気にしない文字列マッチをするシンプルな関数です。

```hs
strcmp s1 s2 = case (s1, s2) of
  ([], []) -> True
  (s1:ss1, s2:ss2)
    | toUpper s1 == toUpper s2 ->
      strcmp ss1 ss2
    | otherwise -> False
  _ -> False
```

## クラス
Haskellの関数は特定の型か型の集合に対して動くように定義され、一度以上定義することはできません。ほとんどの言語は"オーバーロード"の概念をサポートしており、引数の型に依存した異なった振る舞いを持つことができます。Haskellは`class`と`instance`宣言を通してオーバーロードを達成します。`class`定義はクラスのメンバー(例えばインスタンス)ならどんな型でも適用できる1つ以上の関数を定義します。クラスはJavaやC#のインターフェイスに似ており、インスタンスはインターフェイスの具体的な実装に似ています。

クラスは1つ以上の型変数を宣言しなければなりません。技術的にHaskell98は1つの型変数だけを許しますが、ほとんどのHaskell実装はいわゆる_マルチパラメータ_をサポートします。それは1つ以上の型変数を許可します。

与えられた型に味を付けるクラスを定義します。

```hs
class Flavor a where
  flavor :: a -> String
```

関数の型シグネチャだけを与える宣言をしていることに注意してください。ここでは実装を与えていません(いくつかの例外はデフォルト実装を見てください)。続いて、いくつかのインスタンスを定義します。

```hs
instance Flavor Bool where
  flavor _ = "sweet"

instance Flavor Char where
  flavor _ = "sour"
```

`flavor True`を評価します。

```hs
> flavor True
"sweet"
```

`flavor 'x'`は

```hs
> flavor 'x'
"sour"
```

### デフォルト実装
クラスの関数にデフォルト実装を与えることができます。クラスの他の表現で特定の関数を定義出来る時に便利です。デフォルト実装は他の関数の1つに関数本体を与えることで定義されます。標準的な例は`Eq`で、これは`/=`(不等号)を`==`で定義しています。

```hs
class Eq a where
  (==) :: a -> a -> Bool
  (/=) :: a -> a -> Bool
  (/=) a b = not (a == b)
```

再帰的定義も作ることができます。引き続き`Eq`を例に、`==`は`/=`で定義されています。

```hs
(==) a b = not (a /= b)
```

しかし、もしインスタンスがメンバー関数の十分な具体的な実装を与えられないと、そのインスタンスを使うプログラムはループします。

## データ
いわゆる_代数的データ型_は以下のように定義できます。

```hs
data MyType = MyValue1 | MyValue2
```

`MyValue` は型の_名前_です。`MyValue1`と`MyValue2`は型の_値_で、コンストラクタと呼ばれます。複数のコンストラクタは'|'の文字で仕切られています。型とコンストラクタの名前は大文字で始まって_いなければなりません_。そうでなければ構文エラーです。

### 引数のあるコンストラクタ
先の型は列挙型として以外は面白くありません。引数を取るコンストラクタは宣言できて、より多くの情報を持つことが許されています。

```hs
data Point = TwoD Int Int
  | Three Int Int Int
```

それぞれのコンストラクタの引数は_型_の名前ですで、コンストラクタではありません。この種の宣言は間違いです。

```hs
data Poly = Triangle TwoD TwoD TwoD
```

代わりに`Point`型を使わなければなりません。

```hs
data Poly = Triangle Point Point Point
```

### 型とコンストラクタの名前
型とコンストラクタの名前は同じにすることができます。なぜなら混乱を起こす所で使われることはないからです。例えば

```hs
data User = User String | Admin String
```

これは2つのコンストラクタ、`User`と`Admin`を持つ`User`という名前の型です。関数でこの型を使うことは違いを明確にします。

```hs
withUser (User _) = "normal user."
withUser (Admin _) = "admin user."
```

いつくかの文献ではこの習慣を_洒落_として参照します。

### 型変数
いわゆる_多相的な_データ型の宣言をすることは宣言に型変数を追加することと同じくらい簡単です。

```hs
data Slot1 a = Slot1 a | Empty1
```

これは2つのコンストラクタ、`Slot1`と`Empty1`を持つ`Slot1`型を宣言します。`Slot1`コンストラクタは_あらゆる_型の引数でも取ることができます。そしてそれを`a`という型変数で表しています。

コンストラクタに型変数と明示的な型を混ぜることもできます。

```hs
data Slot2 a = Slot2 a Int | Empty2
```

上記の`Slot2`コンストラクタはあらゆる型の値と`Int`の値を取ります。

### レコード構文
コンストラクタの引数は上記のような位置的なものか、それぞれの引数に名前を与えたレコード構文を使ったもののどちらかで宣言することができます。例えばこれは妥当な名前の引数の`Contact`型の宣言です。

```hs
data Contact = Contact { ctName :: String
      , ctEmail :: String
      , ctPhone :: String }
```

これらの名前は_セレクタ_や_アクセサ_関数として参照され、ただの関数です。小文字かアンダースコアで始まっていなくてはならず、スコープの他の関数と同じ名前を持つことはできません。従って"`ct`"をそれぞれに付けています。(同じ型の)複数のコンストラクタは同じ型の値に同じ名前のアクセサ関数を使うことができますが、もしアクセサが全てのコンストラクタに使われていないと危険かもしれません。このわざとらしい例を考えてください。

```hs
data Con = Cont { conValue :: String }
  | Uncon { conValue :: String }
  | Noncon

whichCon con = "convalue is " ++
  conValue con
```

もし`whichCon`が`Noncon`値で呼ばれるとランタイムエラーが起きます。

最後に、他のところで説明したように、これらの名前はパターンマッチング、引数捕捉、"更新"に使うことができます。

### 導出
多くの型は退屈な定義が必要になる共通の演算があります。文字列に変換したり文字列から変換したり、同値性の比較、シークエンスの処理。これらの能力はHaskellでは型クラスを使って定義します。

これら7つの演算はとてもありふれたものなので、Haskellは関連する型に型クラスを自動的に実装する`deriving`キーワードを提供しています。`Eq`、`Read`、`Show`、`Ord`、`Enum`、`Ix`、`Bounded`です。

2つの`deriving`の形式が可能です。1つ目は1つのクラスだけ導出する型の時に使われます。

```hs
data Priority = Low | Medium | High
  deriving Show
```

2つ目は複数クラスを導出する時に使われます。

```hs
data Alarm = Soft | Loud | Deafening
  deriving (Read, Show)
```

上記の7つ以外の`deriving`は構文エラーです。

### クラス制約
データ型は型変数でのクラス制約を付けて宣言することができますが、この慣例は非推奨です。モジュールシステムを使った"生の"データコンストラクタを隠し、妥当な制約を適用する代わりに"スマートな"コンストラクタをエクスポートする方が良いです。どんな場合でも、使われる構文は

```hs
data (Num a) => SomeNumber a = Two a a
  | Three a a a
```

これは1つの型変数の引数を取る`SomeNumber`型です。妥当な型は`Num`クラスです。

## 導出
`dta`の`deriving`を見てください。

## Do
`do`キーワードはそれに続くコードがモナドの文脈にあることを表します。文は改行で分けられ、割り当ては`<-`であることを表し、`let`は`in`キーワードを必要としないことを表します。

### IfとIO
`if`はIOと使う時にはトリッキーです。概念的に他の文脈における`if`と違いはないですが、直感的に開発するのは難しいです。`System.Directory`の`doesFileExists`関数を考えます。

```hs
doesFileExist :: FilePath -> IO Bool
```

`if` 文はこの"シグネチャ"を持ちます。

```hs
if-then-else :: Bool -> a -> a -> a
```

つまり、`Bool`値を取って情況に応じた値を評価します。この型シグネチャから`doesFileExist`は`if`に直接使えないことがはっきりとします。

```hs
wrong fileName =
  if doesFileExist fileName
    then ...
    else ...
```

つまり、`doesFileExist`の結果は`IO Bool`値になり、`if`は`Bool`値を求めます。代わりにIOアクションによって正しい値を"抽出"しなければなりません。

```hs
right1 fileName = do
  exists <- doesFileExist fileName
  if exists
    then return 1
    else return 0
```

`return`の使い方に気を付けてください。`do`は`IO`モナドの中に入れるので、`return`を通して以外、"外に出る"ことができません。`if`を直列で使う必要はありません。`let`を使って状況を評価し値を手にいれることができます。

```hs
right2 fileName = do
  exists <- doesFileExist fileName
  let result =
        if exists
          then 1
          else 0
  return result
```

もう一度`return`に気を付けてください。これを`let`の中に入れることはできません。代わりに関数の最後に一度使うことができます。

### 複数のdo
`do`を`if`か`case`と一緒に使う時、枝のどちらかが文を持つならばもう一つの`do`が必要になります。`if`を使った例は

```hs
countBytes1 f =
  do
    putStrLn "Enter a filename."
    args <- getLine
    if length args == 0
      -- 'do'なし
      then putStrLn "No filename given."
      else
        -- 複数行が必要
        -- 新しい'do'
        do
          f <- readFile args
          putStrLn ("The file is " ++
            show (length f)
            ++ " bytes long.")
```

そして`case`を使ったものは

```hs
countBytes2 =
  do
    putStrLn "Enter a filename."
    args <- getLine
    case args of
      [] -> putStrLn "No args given."
      file -> do
        f <- readFile file
        putStrLn ("The file is " ++
          show (length f)
          ++ " bytes long.")
```

代わりになる構文はセミコロンと波括弧です。`do`は必要なのは同じですが、インデントは不要です。このコードは`case`の例ですが、`if`も原理は同じです。

```hs
countBytes3 =
  do
    putStrLn "Enter a filename."
    args <- getLine
    case args of
      [] -> putStrLn "No args given."
      file -> do { f <- readFile file;
        putStrLn ("The file is " ++
          show (length f)
          ++ " bytes long."; }
```

## エクスポート
モジュールのセクションを見てください。

## If, Then, Else
`if`は常に値を"返します"。式であって、フローを操作する文ではありません。この関数は与えられた文字列が小文字で始まっているかテストし、もしそうであれば大文字に変換します。

```hs
-- 最初の文字を取得するために
-- パターンマッチングを使う
sentenceCase (s:rest) =
  if isLower s
  then toUpper s : rest
  else s : rest
-- 他の場合は空文字列
sentenceCase _ = []
```

## インポート
モジュールのセクションを見てください。

## In
`let` のセクションを見てください。

## Infix, infixl, infixr
演算子のセクションを見てください。

## インスタンス
型クラスのセクションを見てください。

## Let
局所関数は関数の中で`let`を使って定義することができます。`let`キーワードには常に`in`が続かなければいけません。`in`キーワードは`let`キーワードと同じインデントになくてはなりません。関数は同じスコープ内の他の全ての関数と変数にアクセスできるように定義されます(`let`で定義されたものも含みます)。この例では、`mult`は引数`n`に`x`を乗算します。そしてそれはオリジナルの`multiples`に渡され、`mult`はmapによって10までの数にxを乗算するのに使われます。

```hs
multiples x =
  let mult n = n * x
  in map mult [1..10]
```

引数の無い`let` "関数"は実際に定数で、一度評価されると外側の関数の呼び出しのために再度評価されることはありません。これは関数の共通部分の捕捉と再利用に便利です。これは数のリストの合計とその平均を与える馬鹿馬鹿しい例です。`number`を`1`から`m`までのリストとし、一度の`listStats`の呼び出しに対して一度しか評価されません。同様に、`total`と`avg`も一度の呼び出しに対して一度しか評価されません。

```hs
listStats m =
  let numbers = [1..m]
      total = sum numbers
      avg = total / m
  in "total: " ++ show total ++
     ", avg: " ++ show avg
```

### 分解(Deconstruction)
`let` 定義の左辺は引数がサブコンポーネントにアクセスできる時、分解もできます。この定義は文字列から最初の3文字を抽出します。

```hs
firstThree str =
  let (a:b:c:_) = str
  in "Initial three characters are: " ++
     show a ++ ", " ++
     show b ++ ", and " ++
     show c
```

以下のものとは違うことに注目してください。これはちょうど3文字の文字列の時だけ動きます。

```hs
onlyThree str =
  let (a:b:c:[]) = str
  in "The characters given are: " ++
     show a ++ ", " ++
     show b ++ ", and " ++
     show c
```

## Of
`case` のセクションを見てください。

## モジュール
モジュールは関数、型、クラス、インスタンス、その他モジュールををエクスポートする要約(compilation)の単位です。モジュールは1つのファイルだけに定義されますが、そのエクスポートは複数のソースに由来します。Haskellのモジュールを作るには、一番上にモジュール宣言を加えるだけです。

```hs
module MyModule where
```

モジュールの名前は大文字で始まっていなくてはなりませんが、それ以外はピリオドと数字とアンダースコアを含めることができます。ピリオドは階層を意味し、Haskellコンパイラはそれらをファイルのディレクトリの印として使いますが、それ以外の意味はありません。

Haskellコミュニティは`Data`、`System`、`Network`などの標準化されたトップレベルモジュールを持っています。もし公にリリースするならば、自身のモジュールが適切な場所にあるのか相談してください。

### インポート
Haskellの標準ライブラリはいくつかのモジュールに分けられています。ソースファイルにインポートすることでそれらのライブラリの機能を使うことができます。ライブラリによってエクスポートされているもの全てをインポートするには、モジュールの名前を使います。

```hs
import Text.Read
```

_全て_は正に全てを意味します。関数、データ型、コンストラクタ、クラス宣言、モジュールによってインポートされエクスポートされたその他のモジュールでさえです。

インポートする名前の列挙によって選択的にインポートされます。例えば、`Text.Read`からいくつかの関数をインポートするには、

```hs
import Text.Read (readParen, lex)
```

データ型はいくつかの方法によってインポートされます。コンストラクタなしに型をインポートするには、

```hs
import Text.Read (Lexme)
```

もちろん、これは`Lexme`型の値でパターンマッチすることを妨げます。1つ以上のコンストラクタを明示的にインポートすることができます。

```hs
import Text.Read (Lexme(Ident, Symbol))
```

与えられた型の全てのコンストラクタをインポートするには、

```hs
import Text.Read (Lexme(..))
```

クラスの場合、データ型のコンストラクタをインポートするのに似た構文を使って、クラスに定義された関数をインポートすることができます。

```hs
import Text.Read (Read(readsPrec
                     , readList))
```

データ型とは違って、クラスの全ての関数は明示的に除外しなければインポートされることに注意してください。クラス*だけ*をインポートするには、この構文を使ってください。

```hs
import Text.Read (Read())
```

### 除外インポート
モジュールから全てではないが、ほとんどの名前をインポートする場合、全てを並べるのは退屈なものです。そのため、`hiding`キーワードを通して明示したインポートもできます。

```hs
import Data.Char hiding (isControl
                       , isMark)
```

インスタンス宣言、あらゆる型、関数、コンストラクタ、クラスを除外できます。

### インスタンス宣言
`instance` 宣言はインポートから除外することは_できない_ことに注意してください。モジュールの全ての`instance`宣言はモジュールがインポートされた時にインポートされます。

### 修飾名付きインポート
モジュールからエクスポートされた名前(例えば関数、型、演算子など)は修飾名付きインポート(qualified import)を通して付けられた接頭辞を持つことができます。これは`Prelude`の関数と同じ名前の大量の関数を持つモジュールにおいて特に便利です。`Data.Set`は良い例です。

```hs
import qualified Data.Set as Set
```

この形式は`Data.Set`にエクスポートされた関数、型、コンストラクタ、その他の名前を与えられた_エイリアス_(例えば`Set`)で修飾されることを要求します。これはリストからすべての重複を除く1つの方法です。

```hs
removeDup a =
  Set.toList (Set.fromList a)
```

2つ目の形式はエイリアスを作りません。代わりに、接頭辞はモジュールの名前となります。文字列が全て大文字かどうかをチェックする単純な関数を書くことができます。

```hs
import qualified Char

allUpper str =
  all Char.isUpper str
```

接頭辞の明示を除いて、修飾名付きインポートは普通のインポートと同じ構文をサポートします。インポートされた名前は上記と同じように制限されます。

### エクスポート
もしエクスポートするもののリストが与えられなかった場合、全ての関数、型、コンストラクタなどがモジュールをインポートしたところで有効になります。インポートされたモジュールはこの場合エクスポート_されない_ことに注意してください。エクスポートされる名前の制限は`where`キーワードの後に括弧で囲まれた名前のリストを加えることで行うことができます。

```hs
module MyModule (MyType
  , MyClass
  , myFunc1
  ...)
where
```

ここではエクスポートされた関数、型、コンストラクタ、クラスを明示するのに、少しの違いを除いてインポートに使われる構文と同じ構文が使うことができます。もしモジュールが他のモジュールをインポートしているなら、モジュールもエクスポートできます。

```hs
module MyBigModule (module Data.Set
  , module Data.Char)
where

import Data.Set
import Data.Char
```

モジュールは自身さえも再エクスポートでき、それは全てのローカル定義とインポートされたモジュールをエクスポートする時に便利です。以下は自身と`Data.Set`をエクスポートしますが、`Data.Char`はしません。

```hs
module AnotherBigModule (module Data.Set
  , module AnotherBigModule)
where

import Data.Set
import Data.Char
```

## Newtype
`data` は新しい値、`type`はシノニムを作るだけですが、`newtype`はその間辺りのものです。`newtype`の構文はかなり制限されていて、ただ1つのコンストラクタしか定義できず、コンストラクタは1つだけ引数を取ることができます。前述の例に続いて、以下のように`Phone`型を定義します。

```hs
newtype Home = H String
newtype Work = W String
data Phone = Phone Home Work
```

`type` と違って、`Phone`の`H`と`W`は`String`値では_ありません_。型チェッカーはこれらを全く新しい型として扱います。これは前述の`lowerName`関数はコンパイルされないことを意味しています。以下は型エラーとなります。

```hs
lPhone (Phone hm wk) =
  Phone (lower hm) (lower wk)
```

代わりに、`lower`を適用する値を得るためにパターンマッチングを使わないといけません。

```hs
lPhone (Phone (H hm) (W wk)) =
  Phone ((H (lower hm)) ((W (lower wk))
```

重要な見解はこのキーワードは新しい値を導入しないことです。代わりに新しい型を導入します。これは2つのとても便利な性質をもたらします。

* 実際に新しい値を作らないので、新しい型(new type)はランタイムコストがありません。言い換えるとnewtypeは完全にタダです!
* 型チェッカーが`Int`や`String`のような共通の型がプログラマによって明示される制限された方法で使われることを強制することができます。

最後に、`data`宣言に付けられるどんな`deriving`節も`newtype`宣言に使えることに注意してください。

## Return
`do` を見てください。

## Type
このキーワードは*型シノニム*(すなわちエイリアス)を定義します。このキーワードは`data`や`newtype`のような新しい型を定義しません。コードのドキュメントには便利ですが、その他の点では関数や値で与えられた実際の型には影響を与えません。例えば、`Person`型はこのように定義できますが、

```hs
data Person = Person String String
```

ここででコンストラクタの最初の引数はファーストネームを表し、その次はラストネームを表します。しかし、2つの順番と意味は全く明白ではありません。`type`宣言が役に立ちます。

```hs
type FirstName = String
type LastName = String
data Person = Person FirstName LastName
```

`type` はシノニムを導入するので、型チェックは少しも影響を受けません。`lower`関数は

```hs
lower s = map toLower s
```

と定義され、

```hs
lower :: String -> String
```

という型を持ち、`FirstName`型か`LastName`型の値を難なく使うことができます。

## Where
`let` と似ていて、`where`は局所関数と定数を定義します。`where`定義のスコープは今の関数です。もし関数がパターンマッチを通して複数の定義に分割されていているなら、`where`節はその定義だけに適用されます。例えば、以下の`result`関数は`strlen`関数に与えられた引数によって違う意味を持ちます。

```hs
strlen [] = result
  where result = "No string given!"
strlen f = result ++ " characters long!"
  where result = show (length f)
```

### Where vs Let
`where` 節は関数定義のレベルだけに定義されます。通常、`let` 定義のスコープと同一です。唯一の違いはガードが使われる時です。`where`節のスコープは全てのガードに渡ります。対照的に`let`式のスコープは現在の関数節*と*もしあるならガードです。

# コントリビューター
パッチと有用な提案に寄与した方々に感謝します。Dave Bayer, Evgenij Belikov, Paul Butler, Elisa Firth, Marc Fontaine, Brian Gianforcaro, Cale Gibbard, Andrew Harris, Stephen Hicks, Kurt Hutchinson, Johan Kiviniemi, Patrik Jansson, Adrian Neumann, Barak Pearlmutter, Lanny Ripple, Markus Roberts, Holger Siegel, Falko Spiller, Adam Vogt, Leif Warner, and Jeff Zaroyko

# バージョン
バージョン2.9です。ソースはGitHubにあります(http://github.com/m4dc4p/cheatsheet )。最新のリリースされたバージョンのPDFは http://cheatsheet.codeslower.com からダウンロードできます。他のプロジェクトと執筆にCodeSlower.com( http://blog.codeslower.com/ )を訪れてください。