2006-09-01から1ヶ月間の記事一覧

ポイントフリースタイル

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

部分適用

たとえば、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節

はてな記法が裏目に出る

Haskellにおいて空リストを表す が一行に二つあると直接書けない…。([http://hatenadiary.g.hatena.ne.jp/keyword/%e8%87%aa%e5%8b%95%e3%83%aa%e3%83%b3%e3%82%af%e3%82%92%e6%ad%a2%e3%82%81%e3%82%8b%ef%bc%88%e8%87%aa%e5%8b%95%e3%83%aa%e3%83%b3%e3%8…

"" と []

ghci において、"" を評価した結果は "" であり、 を評価した結果は となる。['a', 'b', 'c'] を評価すると "abc" になるにもかかわらず、である。一瞬何でだろうと思ったが、よく考えてみれば当たり前の話で、[] の型は [a] だが、"" の型は [Char] なのだ…

リスト

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 最外簡約 関数を展開してから引数を簡…

時蠅

わー、いつのまにかピッケル本の改訂版が出てるー。初版まだ半分も読んでないのにー。まぁ、日常的にRuby使わないなら読む必要ない部分も多いんだけども。ライブラリとかは必要になったらその都度読む。カタログですカタログ。人気のある本をとりあえず買っ…

四章のまとめ

関数 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…

echo

{- Haskell -} import System main = do args <- getArgs putStrLn $ unwords args モジュール すべての関数や変数はモジュールに所属する import宣言でインポートする Main module main変数を含むモジュール デフォルトでは、外部にmain変数だけを公開 Prel…

三章のまとめ

関数 map f xs concat xs concatMap f xs replicate n x a == b

map関数

{- Haskell -} map :: (a -> b) -> [a] -> [b] map f [] = [] map f (x:xs) = f x : map f xs (* OCaml *) let rec map f = function [] -> [] | x :: xs -> f x :: map f xs

expand

ver.0(タブを'@'に置換) main = do cs <- getContents putStr $ expand cs expand :: String -> String expand cs = map translate cs translate :: Char -> Char translate c = if c == '\t' then '@' else c 高階関数 引数に関数を取る if式 それ自体が値…

Haskell OCaml 整数 Int int 文字 Char char 文字列 String = [Char] string 真偽値 Bool(True) bool(true) 型aのリスト [a] ([1, 2, 3]) a list ([1; 2; 3]) 型変数 (a, b, c) ('a, 'b, 'c) ※ ()内はリテラルの例多相型: 型変数を含む型 型宣言 {- Haskell …