Hatena::Grouphaskell

lnzntのHaskell日記 このページをアンテナに追加 RSSフィード

2011年08月05日(金)

関数定義 いろいろ

| 23:59 | 関数定義 いろいろ - lnzntのHaskell日記 を含むブックマーク はてなブックマーク - 関数定義 いろいろ - lnzntのHaskell日記 関数定義 いろいろ - lnzntのHaskell日記 のブックマークコメント

簡単な方法

isDigit  :: Char -> Bool
isDigit c = c >= '0' && c <= '9'

条件式を使う

abs :: Int -> Int
abs n = if n >= 0 then n else -n

Haskell では 「else 部」の省略はできない。

ガード付きの等式

abs n | n >= 0    = n
      | otherwise = -n   -- otherwise == True と定義されている

パターンマッチ

not :: Bool -> Bool
not False = True
not True  = False

(&&) :: Bool -> Bool -> Bool
True && True = True
_    && _    = False

True  && b = b
False && _ = False

「_」はワイルドカード。

タプルパターン

fst       :: (a, b) -> a
fst (x,_) = x

snd       :: (a, b) -> b
snd (_,y) = y

リストパターン

test         :: [Char] -> Bool -- test は先頭が 'a' か調べる関数
test ('a':_) = True
test _       = False

演算子「:」は cons 演算子と呼ばれる。

cons演算子
既存のリストに新しい要素を追加することで新しいリストを作成する。
  [1,2,3] は 1:(2:(3:[])) の略記法
null       :: [a] -> Bool
null []     = True
null (_:_)  = False

head       :: [a] -> a
head (x:_) = x

tail        :: [a] -> [a]
tail (_:xs) = xs

cons 演算子を使ったパターンは括弧で囲む。

n + k パターン

n は整数の変数で、k は 0 より大きな整数の定数。

pred       :: Int -> Int  -- pred は正数を一つ前の正数に変換する関数
pred 0       = 0
pred (n + 1) = n
  • k 以上である整数のみに合致する
  • n + k パターンは括弧で囲む

ラムダ式(λ式)

Prelude> (\x -> x + x) 2       -- x を引数に取り x + x を返す無名関数
4
Prelude> (\x y -> x + y) 1 2   -- x, y を引数に取り x + y を返す無名関数
3
  add x y = x + y
  は、
  add = \x -> (\y -> x + y)   -- カリー化された形式
  のような意味を持つ

...分からんです。

ちょっと Ruby で書いてみます。

add = -> x, y { x + y }
add.(1,2)  # => 3
は、
add = -> x { -> y { x + y } }
p add.(1).(2)    # => 3
あるいは、
add = -> x, y { x + y }.curry.curry
p add.(1).(2)    # => 3

...のようなことを言っているんだと思います。。。???

関数を返す関数の定義

  const   :: a -> (b -> a)
  const x = \_ -> x

こいつも Rubyで書いて理解。。。

  const = -> a { -> b { a } }

セクション

  (+) 1 2   -- 演算子を括弧で囲む。カリー化された関数となる
  (1+) 2    -- 引数を一つ括弧に入れられる
  (+2) 1
  + が演算子であれば、引数 x と y に対し (+)、(x+)、(+y) はセクションである

セクション演算子の型を宣言する時に必要

  (&&) :: Bool -> Bool -> Bool

二項演算子を引数として渡す時に必要

  and :: [Bool] -> [Bool]
  and = folder (&&) True

----

今回はここまで。

----

参考書籍

今日の範囲は第4章。

プログラミングHaskell

プログラミングHaskell