Mercurial > hg > Papers > 2014 > toma-master
changeset 8:a145ceb871d3
describe chapter 1
author | Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp> |
---|---|
date | Sun, 19 Jan 2014 23:30:12 +0900 |
parents | f354d23bd80d |
children | 70bda541eb1d |
files | paper/chapter1.tex paper/master_paper.tex |
diffstat | 2 files changed, 130 insertions(+), 1 deletions(-) [+] |
line wrap: on
line diff
--- a/paper/chapter1.tex Sun Jan 19 16:36:37 2014 +0900 +++ b/paper/chapter1.tex Sun Jan 19 23:30:12 2014 +0900 @@ -28,5 +28,124 @@ また、リストの畳み込み関数といった再帰を用いた関数が標準ライブラリで提供されている。 \section{型} -\section{Monad} +Haskell は静的型付け言語である。 +全ての型に起因するエラーはコンパイル時に捕捉される。 +コンパイル時に多くのエラーを見つけてくれるため、プログラマがプログラムの正しさを確認するのに役に立つ。 +また、Haskell は型を明示しなくても、処理系により自動的に型が推論される。 +型安全を保ちながら、ほとんどの部分で型宣言を省略することができる\footnote{明示的な型宣言は可読性の向上や問題の発見に役に立つため、トップレベルの関数には型を明記することが一般的である。}。 + +\subsection{データ型} +Haskellの標準なデータ型には、Int 型や、Float 型、Bool 型、Char 型などが存在する。 +data キーワードを用いることで、自作のデータ型を作ることもできる。 +標準ライブラリにおける Bool 型は\ref{bool}のように定義されている。 + +\begin{lstlisting}[label=bool, caption=Bool型の定義] +data Bool = False | True +\end{lstlisting} + +この型宣言は、「Bool 型は True または False の値を取り得る」ということを表している。 + +\subsection{型変数} +Haskell の型は多相的である。 +型変数を使い、型を抽象化できる。 +型変数は、型安全を保ちながら、関数を複数の型に対して動作するようにできる。 +Haskell の型の名前は全て大文字から始まるが、型変数は小文字から始まる。 +任意の型のリストを引数に取り、その型の先頭要素を返すという関数 head の型は\ref{type_variable}のように定義される。 + +\begin{lstlisting}[label=type_variable, caption=型変数] +head :: [a] -> a +\end{lstlisting} + +データ型も型変数を使うことができる。例えばリストといったデータ型は、その要素の型を型変数として定義する。 +これらのデータ型は、型引数を受け取って具体型を生成する。 +言うまでもなく、型推論があるため明示的に型引数を渡す必要はない。 + +\subsection{型クラス} +型クラスは型の振る舞いを定義するものである。 +ある型クラスのインスタンスである型は、その型クラスに属する関数の集まりを実装する。 +ある型を型クラスのインスタンスにしようとする場合、それらの関数がその型ではどのような意味になるのか定義する。 +例えば、Eq 型クラスのインスタンスとなる型は等値性をテストできる。Show 型クラスのインスタンスとなる型は文字列として表現できる。 +いくつかの関数には型クラスが制約となるものがある。 +演算子 * の引数は、数を表す型クラスである Num 型クラスである必要がある。 + +\begin{lstlisting}[label=multiply, caption=演算子 *] +(*) :: Num a => a -> a -> a +\end{lstlisting} + +1つの型はいくつもの型クラスのインスタンスとなることができる。 +自作のデータ型を作成する際に型クラスを利用することで、既存の Haskell ライブラリを利用できる。 + +\section{モナド} +Haskell では、さまざまな目的にモナドを使う。 +モナドを用いることで I/O 処理を行うこともできる。 + +モナドとなる型は、型変数として具体型をただ1つ取る。 +これにより何かしらのコンテナに包まれた値を実現する。 +モナドの振る舞いは型クラスとして実装し、メソッドとして return および $>$$>$= を定義する。 +return は値を持ち上げてコンテナに包む機能を実装する。 +$>$$>$= は、「コンテナに包まれた値」と、「普通の値を取りコンテナに包まれた値を返す関数」を引数にとり、コンテナに包まれた値をその関数に適用する。 +この2つの関数を利用することにより、状態を保ったまま関数を繋いでいくことができる。 + +Haskellで副作用を持つ処理を実行するには、IO モナドを利用する。 +IO モナドは、mainという名前と関連づけることで初めて実行される。 +IO モナド自体は単なる命令書であり、引数として渡したりするだけでは実行されない。 +そのため、IO モナドをリストに格納したりすることも可能である。 + \section{並列実行} +Haskellはデフォルトではシングルスレッドで走る。 +並列に動かしたい場合は、-threaded 付きでコンパイルし、RTS の -N オプションを付けて実行する。 +-N オプションで指定された数だけ、OSのスレッドが立ち上がり実行される。 + +\begin{lstlisting}[language=bash, label=concurrent, caption=並列実行の様子] +$ ghc -O2 par.hs -threaded +$ ./par +RTS -N2 +\end{lstlisting} + +当然これだけでは並列に動かず、並列に実行できるようにプログラムを書く必要がある。 + +Haskell は遅延評価を行うため、必要となるまで式の評価が遅延される。 +普段は気にする必要はないが、並列実行ではどのように評価されるか意識する必要がある。 +並列に動くように処理を分割したとしても、値が必要になるまで評価されない。 +この問題は、Control.DeepSeq モジュールにある deepseq 関数を使用し、式を即時評価することで解決できる。 + +Haskellの並列化手法はいくつかあるが、その中で最もシンプルなのは Eval モナドを利用することである。 +Control.Parallel.Strategies モジュールをインポートすることで使用できる。 + + +\begin{lstlisting}[label=eval, caption=Eval モナド] +data Eval a +instance Monad Eval + +runEval :: Eval a -> a + +rpar :: a -> Eval a +rseq :: a -> Eval a +\end{lstlisting} + +rpar は、引数が並列処理可能であることを示す。 +rseq は、引数を評価し、結果を待つように示す。 +どちらも式が完全に即時評価されるわけではないので、出力を挟んだり、deepseq 関数をうまく活用する必要がある。 +runEval は、評価を実行し結果を返す操作である。 +実際の利用方法として2つのパターンを紹介する。 + + +\begin{lstlisting}[label=rpar/rpar, caption=rpar/rpar] +runEval $ do + a <- rpar (f x) + b <- rpar (f y) + return (a,b) +\end{lstlisting} + +rpar/rpar パターンは単純に並列に動かしたい時に利用する。 +即座に return される。 + +\begin{lstlisting}[label=rpar/rseq/rseq, caption=rpar/rseq/rseq] +runEval $ do + a <- rpar (f x) + b <- rpar (f y) + return (a,b) +\end{lstlisting} + +rpar/rseq/rseq パターンは、f x および f y の結果を待ってから return する。 +他の処理が結果を必要としている時に利用する。 +
--- a/paper/master_paper.tex Sun Jan 19 16:36:37 2014 +0900 +++ b/paper/master_paper.tex Sun Jan 19 23:30:12 2014 +0900 @@ -4,6 +4,16 @@ \usepackage[dvipdfmx]{graphicx} \usepackage{url} \usepackage{comment} +\usepackage{listings,jlisting} + +\lstset{ + language=Haskell,%プログラミング言語によって変える。 + basicstyle={\ttfamily\footnotesize}, + tabsize=2, + frame=single, + breaklines=true,%折り返し + captionpos=b +} \input{font.sty}