|
|
||
リファレンス的な第2部で、このタイミングで基本的な値の説明。どわーっと値に関する話題(各型のリテラルの書き方と数値計算関数とか)があったあとに、catnという関数を作ってみてしめくくり。
まず、いろんな値と関連する関数の説明。
副作用ある関数だと(||)や(&&)の実行順が気になるけど、haskellだと関係ないか。
文脈によって型が解釈されうる。明示的に型指定も可能。数値演算一覧が(p.133)に。演算するときは型に注意。暗黙の変換はしてくれない。変換にはtoIntegerとかを使う。(p.134)に変換関数抜粋。
明示的に型を指定してみた。Intは32bitなのでちょうどあふれる。Integerなら大丈夫。
*Main> (2 ^ 32) :: Int 0 *Main> (2 ^ 32) :: Integer 4294967296
有理数型(Rational)や複素数型(Complex)を使えるようになるモジュールもある。
と思いきや、Rational型はPreludeにあった。
Prelude> (toRational 1) 1%1 Prelude> :t (toRational 1) (toRational 1) :: Rational Prelude> let a = (toRational 3) Prelude> let b = (toRational 4) Prelude> a / b 3%4
(内部的にはUnicodeだがGHCでは入出力のエンコーディング変換が未実装。)
要素の個数と順序固定。要素が一個のタプルはない。
3つめ以降の値を直接とりだす関数は発見できず。パターンマッチで取れということか。
要素が0個のタプル。
:info Enumの結果
class Enum a where succ :: a -> a pred :: a -> a toEnum :: Int -> a -- 数値と値の対応 fromEnum :: a -> Int enumFrom :: a -> [a] enumFromThen :: a -> a -> [a] -- 増分指定 enumFromTo :: a -> a -> [a] -- 終端指定 enumFromThenTo :: a -> a -> a -> [a] -- 増分および終端指定
BoolやOrdering(比較結果を返す型)もEnumに属しているので…
*Main> [(False)..] [False,True] *Main> [(LT)..] [LT,EQ,GT]
ということは…自分で定義した型もEnumの型クラスに属させておけば数列記法が使える。なかなか楽しい。
data MyEnum = A | B | C | D | E | F |G deriving (Show,Enum) -- Enumのインスタンスとして定義 -- 以下、GHCiで読みこんだ後テスト *Main> [(A)..(E)] -- ()でくるまないとパースエラー [A,B,C,D,E] *Main> [(B)..] [B,C,D,E,F,G] *Main> [(A),(C)..(F)] [A,C,E] *Main> [(A),(C)..] [A,C,E,G]
p.148より
[abs x | x <- xs]
…「xsの各要素xについて(abs x)を集める」
要は、
をまとめた記法。上の例では、ひとつのリストを指定していて条件式もないが、クイックソートの例に条件式が、さらにその次に複数リスト指定した組みあわせ列挙の例あり。
全部組みあわせた例を書くとこんなかんじ。
*Main> [(x,y) | x <- [1..10],y <- [1..10] , x * 2 == y] [(1,2),(2,4),(3,6),(4,8),(5,10)]
結局、mapとfilterとconcatがひとつにまとめられているだけだが、mapの入れ子相当のものを簡単に書けるようになっていて、はまると強力。
zipLineNumberで行番号と行ペアのタプルをつくって、それぞれ(の行番号部分を)formatで整形して、最後にまとめて表示。
resolv f (x:xs) = textify x ++ resolve f xs getenv key env = fromMaybe "" $ lookup key env readTemplate id = readFile $ prefix repo ++ "/" ++ id -- に()をおぎなうと以下に resolv f (x:xs) = (textify x) ++ (resolve f xs) getenv key env = fromMaybe "" (lookup key env) readTemplate id = readFile ((prefix repo) ++ ("/" ++ id))
(++)は右結合 (infixr 5)
ちなみに、今回のソースの表示には、http://hatena.g.hatena.ne.jp/hatenagroup/20060616/1150453529 を使って色をつけました。