Haskell

型クラスの継承

ざっとキーワードだけ。型クラスの宣言はclassで行います。宣言の中ではクラスメソッドの型宣言と、クラスメソッドのデフォルト実装を書くことができます。型を型クラスのインスタンスだと宣言する時はinstanceを使います。宣言の中でクラスメソッドの実装を…

型クラスの例

sort :: (Ord a) => [a] -> [a] ここで出てくる「(Ord a) =>」が型クラスの制約を示す構文だそうです。今まで説明で「(Show a) => a -> String」とか「(Eq a) => [a] -> [a] -> Bool」なんて出てきて何だろうと思っていましたけど、これで一つ謎が解けました…

型クラス

型クラスを一言で言うと型に対する制約というので良いのでしょうか。性質とか特徴と捉えた方が分かりやすいような気もしますけどどうなのでしょう。本には例としてsort関数のことが書かれていて、sort関数は整数のリスト・浮動小数点のリスト・文字列のリス…

型の別名と付け替え

type FilePath = String typeを使うと型に別名を付けることができます。 type MyList a = [a] このように型変数を使うこともできます。 newType StackNT a = MkStackNT [a] 今度はnewTypeです。既存の型を元にして新しい型を宣言できるそうです。これという…

代数的データ型その10

再帰的な型です。 data Stack a = Empty | Push a (Stack a) 上記のように自分自身を型の宣言に使えます。と言うわけで本に書いてあった例を基にして、サンプルを作ってみました。 data Stack a = Empty | Push a (Stack a) isEmpty :: Stack a -> Bool isEm…

代数的データ型その9

共用体スタイルについて。 data PTItem = Pram Int | Text String このように複数のデータコンストラクタのうちのいずれかを使うという書き方ができます。どのデータコンストラクタを使ったかの判別はパターンマッチで行えます。 data PTItem = Param Int | …

代数的データ型その8

列挙型スタイルについて。 data OpenMode = ReadOnly | WriteOnly | ReadWrite このように書くそうです。これは「ReadOnly」または「WriteOnly」または「ReadWrite」という意味。これだけなら難しくないですね。

代数的データ型その7

多相的な型の宣言というのが出てきましたが、ここではパス。型コンストラクタとデータコンストラクタは同じ名前を使うことができるそうです。 data Anchor = A { aUrl :: String, aLabel :: String } これまでは上記のように書いていましたが、こんな風に書…

代数的データ型その6

代数的データ型の章はまだまだ続きます。今回はフィールドの更新について。更新と言ってもHaskellでは再代入はできないので、既存の値を元に新しい値を作るのですが、その際に一部のフィールドだけを変更して値を作ることができます。サンプルプログラムを作…

代数的データ型その5

今回はセレクタについて。フィールドラベルを使って代数的データ型を宣言すると、フィールドラベルと同名の関数が自動的に宣言されて、フィールドの値を取得できるとのことです。id:MAS3:20071124#c1195912479のコメントでも使われていました。それでは早速…

代数的データ型その4

データにアクセスするのに専用の関数を作っていますが、無名関数で代用してみました。 data Anchor = A { aUrl :: String, aLabel :: String } main = do putStrLn $ "Url : " ++ (\(A u _) -> u) getAnchor putStrLn $ "Label: " ++ (\(A {aLabel = l}) -> …

代数的データ型その3

data Anchor = A { aUrl :: String, aLabel :: String } というようにフィールドラベルを付けることができます。こうするとフィールド名でデータにアクセスできるようになります。フィールドラベルを使った方法でサンプルを書き換えてみます。 data Anchor =…

代数的データ型その2

data Anchor = A String String このように宣言した型のフィールドにアクセスするにはパターンマッチを利用します。早速サンプルを作って試してみます。 data Anchor = A String String main = do putStrLn $ "Url : " ++ getUrl getAnchor putStrLn $ "Labe…

代数的データ型

本では、構造体スタイル、列挙型スタイル、共用体スタイルと名付けて3つに分けて説明されています。そのうちの構造体スタイルについて説明を読みました。型を定義する時に使うのはdata宣言。こんな例が出てきました。 data Anchor = A String String Anchor…

Haskellではコンパイル時に型がチェックされます。そういう言語は多いですよね。特徴的なのは型推論。おかげでほとんどの場合型を宣言しなくても大丈夫です。とは言っても完璧ではないので明示的に宣言できるようになっています。そのときに使うのが「::」。…

演習問題

8章の演習問題を解きました。ポイントフリースタイルで書く問題。まずはlstrip lstrip :: String -> String lstrip = dropWhile (== ' ') そしてrstrip rstrip :: String -> String rstrip = reverse . lstrip . reverse 最後にstrip strip :: String -> Str…

ポイントフリースタイル

関数合成や部分適用を使うと、値を返していた関数が、関数を返す関数になります。関数を返す関数というのを言い換えると、関数を定義する関数と言うことになります。関数を関数で定義するコーディングスタイルをポイントフリースタイルと呼ぶそうです。本に…

部分適用

n個の引数を取る関数に対してn個未満の引数で関数を呼び出すと、関数に渡した引数を適用した関数が戻ってきます。厳密には引数を一つ取ってその引数を適用した関数が戻ってきてというのをくり返しているとのことです。なので、引数の数が少ない場合は関数が…

関数合成

複数の関数を合成して一つの関数を作れます。 main = do cs <- getContents print $ numberOfLines cs numberOfLines :: String -> Int numberOfLines = length . lines これまでだとこう書いていました。 numberOfLines cs = length $ lines cs 引数を書か…

無名関数

8章の関数の章に入りました。新登場は無名関数。\を使って書きます。無名関数は高階関数と組み合わせて利用可能。いちいち関数定義をしなくても高階関数が使えます。無名関数でもパターンマッチが使えますが、パターンは一つだけ。

読めるけど書けない

第7章の練習問題が解けませんでした。回答例を読むと何をやっているのかは分かるので、読めるけど書けないという状態。まだまだ理解が足りませんね。

let式とwhere節

大雑把な理解ですが、let式はローカル変数を使う時に、where節はローカル関数を使う時に登場するもののようです。let式はinとセットですね。let式は式なので値を返し、where節は値は返さないというのが違い。と、書いてみましたが、実はまだあまりよく分かっ…

関数定義

関数名や変数名の先頭はアルファベット小文字か「_」。大文字は使えないのですね。試しに先頭大文字の関数を定義しようとしたら "Invalid type signature" とエラーになりました。二項演算子の定義については使う機会があまりなさそうなので、二項演算子の定…

case式

関数の引数以外でパターンマッチやガードを使いたい時に使えます。なので、他の言語のcase文との関連で覚えるのではなく、パターンマッチとガードを使うための式と覚えた方が良さそうです。

パターンマッチ

ghcコマンドの場合-Wオプションでパターンマッチで実行時エラーが起きる場合に警告してくれるそうです。変数パターン、「_」パターン、リテラルパターン、タプルパターン、リストパターン、データコンストラクタパターン、「@」パターンについての説明を読み…

if式

1行で書くのが一般的とのこと。以下の書き方もよく使われるそうです。 if c == '\t' then '@' else c if c == '\t' then '@' else c 式の継続を使った書き方ですね。

レイアウト

do式を使って複数の式を書く時にはインデントを揃えていました。インデントを使う以外にも{ }と;を使って書くこともできます。オフサイドラインはdo等のあとに現れる単語の位置によって決まるので、以下のどちらの書き方も可能です。 main = do cs <- getCon…

コメント

これが出てくるのを待っていました。一行コメントは--。ブロックコメントは{- -}。ブロックコメントはネストできます。珍しいですね。リテレイト形式というのがあるそうです。これはコメントがメインで、コードがおまけのような書き方。

練習問題

ソースコードがどのように解析されるかを括弧で答える問題。問題はこの3問。 resolve f (x:xs) = textify x ++ resolve f xs getenv key env = fromMaybe "" $ lookup key env readTemplate id = readFile $ prefix repo ++ "/" ++ id 私の答えはこれ。 reso…

実習 cat -n

関数適用が最も優先順位が高くて、どの演算子よりも優先的に結合します。わかりにくいところらしいです。タプルのパターンマッチが出てきました。と言ってもちょっと出てきただけでちゃんとした説明はもう少し後ろで出てくるみたいです。