ふつけるメモ

インポート

import [qualified] モジュール名 [(インポートリスト)| hiding (ハイディングリスト)] [as エイリアス] 明示的にPreludeのimport宣言をしない場合は、暗黙的に「import Prelude」が宣言される インポートしたエンティティは、import宣言を書いたモジュール…

エクスポート

module モジュール名 [(エクスポートリスト)] where -- []内はoptional 他のモジュールにインポートできるようにする module宣言を省略すると、「module Main (main) where」が補われる。 エクスポートリストを省略すると、すべてのエンティティがエクスポー…

名前空間

エンティティの名前空間がモジュールごとに分かれている エンティティ 変数 型コンストラクタ データコンストラクタ フィールドラベル 型クラス クラスメソッド

階層化ライブラリ

Haskell Hierarchical Libraries

主要な型クラス

Eq : 同値関係が定義できる Ord : 順序関係が定義できる Show : 文字列に変換できる Read : 文字列から変換できる Num : 数値型 Integral : 整数型 Numのサブクラス Fractional : 小数型 Numのサブクラス

型クラス

Java等のクラスとは違い、特定の型コンストラクタの集合を定義する。 多相型に制約をつけるためのもの アドホック多相: 制約のついた多相性 パラメータ多相: 制約の無い多相性 クラスメソッド 型クラスを特徴付ける関数 ある型クラスに属する型は、その型ク…

代数的データ型

data宣言 新しい型を定義する data 型コンストラクタ 型変数1 型変数2 ... = データコンストラクタA 型A1 型A2 ... | データコンストラクタB 型B1 型B2 ... | データコンストラクタC 型C1 型C2 ... : 型コンストラクタとデータコンストラクタの名前空間は別…

型 = 値の集合 型推論 「::」構文による型宣言 多相型: 型変数を含む型

ポイントフリースタイル

関数合成や部分適用を使って、関数を関数で定義するコーディングスタイル 変数が減るのでコードが読みやすくなる 型宣言や関数名をしっかり書かないとわけわからなくなる

部分適用

たとえば、f :: Int -> Int -> Int だとすると、 (f 5) :: Int -> Int 二項演算の場合 セクションと呼ぶ 第二引数(右辺)を渡して第一引数をパラメータ化することもできる。 `` を使えば任意の二項演算に対してこれが使える。 increment n = (+ 1) n -- 「n…

関数合成

(.) :: (b -> c) -> (a -> b) -> (a -> c) (f . g) x ≡ f (g x) f . g . h ≡ f . (g . h) -- 右結合

無名関数

ラムダとして、バックスラッシュ(\)を使う 引数にパターンマッチが使えるが、2つ以上のパターンを順番に試すことはできない {- Haskell -} \x (y:ys) -> x * y (* OCaml *) (* 複数パターンは使えないが複数引数が可能 *) fun x y -> x * y (* 複数引数は使…

高階関数

引数や返り値に関数をとる関数

定義・束縛

識別子 1文字目 [a-z_] 2文字目以降 [a-zA-Z0-9_']* 予約語 case , class , data , default , deriving , do else , if , import , in , infix , infixl , infixr , instance let , module , newtype , of , then , type , where , _ 中項演算子 二項関数 → …

パターンマッチとガード

関数定義の一般形 関数名 パターンA1 パターンA2 ... | ガードA1 = 定義A1 | ガードA2 = 定義A2 | ガードA3 = 定義A3 : 関数名 パターンB1 パターンB2 ... | ガードB1 = 定義B1 | ガードB2 = 定義B2 | ガードB3 = 定義B3 : : :一つの関数は複数の引数を持ち…

レイアウト

インデントを揃えることで一つのコードブロックを表す 所属するコードブロックのオフサイドラインよりも深くインデントすると前の行の続きになる 以下はいずれも同じ意味 do foo bar bazdo foo bar bazdo foo bar bazdo { foo bar ; baz }

コメント

-- 一行コメント "--" の後に空白を入れるべし {- ブロックコメント -} ネスト可能 リテレイト形式 Haddock

Haskellの構文

コメント レイアウト if式 パターンマッチ case式 関数定義 let式 where節

リスト

x : xs (cons) null xs xs ++ ys (append) 数列表記 ".."を使って等差数列を記述 [1..7] -- [1, 2, 3, 4, 5, 6, 7] ['a'..'e'] -- ['a', 'b', 'c', 'd', 'e'] [1, 3..11] -- [1, 3, 5, 7, 9, 11] [1..] -- [1, 2, 3, 4, ....] [1, 3..] -- [1, 3, 5, 7, ....…

タプル

値の組。例: (1, "hoge") , (True , 't') .. fst :: (a, b) -> a snd :: (a, b) -> b zip :: [a] -> [b] -> [(a, b)] # lengthは短い方に揃えられる unzip :: [(a, b)] -> ([a], [b]) ユニット 0要素のタプル

文字・文字列

Char Charモジュールの関数 テスト( Char -> Bool ) : isAlpha , isLower , isUpper , isAlphaNum , isDigit , isHexDigit , isOctDigit : isSpace , isAscii , isLatin1 , isPrint , isControl 変換 : toLower , toUpper : ord , chr String Haskellでは[Ch…

数値

整数型 Int : 処理系依存。GHCは32bitの符号付整数値 Integer : 範囲制限無し 浮動小数点数型 Float Double リテラル 8進表記: 0o644 (ぜろおー) 16進表記: 0xff (ぜろえっくす) リテラルがInt/Integer または Float/Double のどれに決まるかは文脈依存 数値…

真偽値

data Bool = True | False deriving (Eq, Ord, ...) : not x , x && y , x || y

primitive

第一級の値(first-class value)、変数束縛の対象となるもの 真偽値 ( Bool ) 数値 ( Int, Integer, Float, Double ) 文字 ( Char ) 文字列 ( String = [Char] ) タプル ( (a, b) ) ユニット ( () ) リスト ( [a] ) 関数 ( a -> b )

遅延評価の利点と欠点

利点 不要な計算を減らせる 無限リストが扱える 大抵のことはリスト処理でできる 欠点 評価順序がわかりづらい スタックトレースが意味をなさないためデバッグしにくい

参照透過性

Referential transparency「同じスコープ内では、同じ式はすべて同じ値を持つ」という性質

if を関数として実装

Haskellは必要呼出し、OCamlは値呼出し {- Haskell -} myIf :: Bool -> a -> a -> a myIf True t e = t myIf False t e = e main = myIf True (putStrLn "then") (putStrLn "else") ---------- 実行結果: then (* OCaml *) let myIf c t e = match c with tr…

評価戦略

値呼出し (call by value) => 最内簡約 名前呼出し(call by name) => 最外簡約 必要呼出し(call by need) => 最外簡約かつグラフ簡約 最内簡約 先に引数を簡約してから関数を展開 square (1+3) → square 4 → 4 * 4 → 16 最外簡約 関数を展開してから引数を簡…

四章のまとめ

関数 unwords xs any f xs filter f xs head xs tail xs List.tails xs xs `List.isPrefixOf` ys アクション System.getArgs

fgrep

import System import List main = do args <- getArgs cs <- getContents putStr $ fgrep (head args) cs fgrep :: String -> String -> String fgrep pattern cs = unlines $ filter match $ lines cs where match :: String -> Bool match line = any pre…