<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>UKSTUDIO &#187; Haskell</title>
	<atom:link href="http://ukstudio.jp/tag/haskell/feed/" rel="self" type="application/rss+xml" />
	<link>http://ukstudio.jp</link>
	<description>いわゆる86世代のブログです</description>
	<lastBuildDate>Wed, 11 Jan 2012 05:53:43 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.2.1</generator>
	<div id='fb-root'></div>
					<script type='text/javascript'>
						window.fbAsyncInit = function()
						{
							FB.init({appId: null, status: true, cookie: true, xfbml: true});
						};
						(function()
						{
							var e = document.createElement('script'); e.async = true;
							e.src = document.location.protocol + '//connect.facebook.net/en_US/all.js';
							document.getElementById('fb-root').appendChild(e);
						}());
					</script>	
						<item>
		<title>ふつケル第3章</title>
		<link>http://ukstudio.jp/2008/02/27/haskell_sec3/</link>
		<comments>http://ukstudio.jp/2008/02/27/haskell_sec3/#comments</comments>
		<pubDate>Tue, 26 Feb 2008 15:50:20 +0000</pubDate>
		<dc:creator>ukstudio</dc:creator>
				<category><![CDATA[article]]></category>
		<category><![CDATA[Haskell]]></category>

		<guid isPermaLink="false">http://ukstudio.sakura.ne.jp/2008/02/27/haskell_sec3/</guid>
		<description><![CDATA[型と値 Haskellには型推論という機能がある。型推論は処理系の方で型を推測し、矛盾なく全ての式が型づけできればコンパイル時にエラーにはならない。Haskell以外にも、OCaml、Scala、MLなど静的型付け関数型言語のほとんどが型推論の機能を供えている。 Haskellの型には、Int(整数値)、Char(文字)、String(文字列)、Bool(真偽値)がある。Intは最低30ビット幅の符号付き整数値を意味する。CharやStringで扱う文字(列)のエンコードにはUnicodeを採用しているが、GHCの実装は中途半端で入出力でのエンコーディング変換などが実装されていない。 また、Int型のリスト、Char型のリストと言う風にリストの型を表現し、Int型のリストの各要素はInt型になる。ソースコード上では[Int]や[Char]と書く。文字列は文字のリストなので[Char]ということになり、別名として上記したString型が用意されている。 関数の型をは引数の型と返り値の型を組合せて表現する。例えば、String -> [String]というのは第1引数の型がString(文字列)で、返り値の型が[String](文字列のリスト)となる。 第1引数の型 -> 第2引数の型 -> ・・・ -> 返り値の型 では、引数の型が決まっていない場合どうするのかと言うと、型変数と言うものを使う。型変数はアルファベット小文字であらわし、アルファベット小文字の部分は好きな型に読み替えてよい。 [a] -> Int Int -> [a] -> [a] 上記の場合だと、1行目は任意の型のリストを引数にもち、Intを返す関数。2行目はIntを第1引数、任意の型のリストを第2引数にもち、第2引数と同じ型のリストを返す関数という意味になる。 関数の型を宣言するには、先程関数の型を表現したものに少し付け足せばいい。Haskellは型推論の機能をもつので必ずしも型の宣言が必要というわけではないが、なるべく宣言しておくのが好ましい。 関数名 :: 第1引数の型 -> 第2引数の型 -> ・・・ -> 返り値の型 高階関数 高階関数とは引数に関数をとる関数のこと。 main = do cs < - getContents putStr $ expand cs expand :: String -> string expand cs = [...]]]></description>
			<content:encoded><![CDATA[				<div class='wpfblike' style='height: 40px;'><fb:like href='http://ukstudio.jp/2008/02/27/haskell_sec3/' layout='default' show_faces='true' width='400' action='like' colorscheme='light' send='false' /></div><h2>型と値</h2>
				<p>Haskellには<strong>型推論</strong>という機能がある。型推論は処理系の方で型を推測し、<strong>矛盾なく全ての式が型づけできればコンパイル時にエラーにはならない</strong>。Haskell以外にも、OCaml、Scala、MLなど静的型付け関数型言語のほとんどが型推論の機能を供えている。</p>
				<p>Haskellの型には、<strong>Int(整数値)、Char(文字)、String(文字列)、Bool(真偽値)</strong>がある。Intは最低30ビット幅の符号付き整数値を意味する。CharやStringで扱う文字(列)のエンコードにはUnicodeを採用しているが、GHCの実装は中途半端で入出力でのエンコーディング変換などが実装されていない。</p>
				<p>また、Int型のリスト、Char型のリストと言う風にリストの型を表現し、Int型のリストの各要素はInt型になる。<strong>ソースコード上では[Int]や[Char]と書く</strong>。文字列は文字のリストなので[Char]ということになり、別名として上記したString型が用意されている。</p>
				<p>関数の型をは引数の型と返り値の型を組合せて表現する。例えば、<strong>String -> [String]というのは第1引数の型がString(文字列)で、返り値の型が[String](文字列のリスト)となる</strong>。</p>
				<pre lang="haskell">
第1引数の型 -> 第2引数の型 -> ・・・ -> 返り値の型
</pre>
				<p>では、引数の型が決まっていない場合どうするのかと言うと、<strong>型変数</strong>と言うものを使う。型変数はアルファベット小文字であらわし、アルファベット小文字の部分は好きな型に読み替えてよい。</p>
				<pre lang="haskell">
[a] -> Int
Int -> [a] -> [a]
</pre>
				<p>上記の場合だと、1行目は任意の型のリストを引数にもち、Intを返す関数。2行目はIntを第1引数、任意の型のリストを第2引数にもち、第2引数と同じ型のリストを返す関数という意味になる。</p>
				<p><strong>関数の型を宣言</strong>するには、先程関数の型を表現したものに少し付け足せばいい。Haskellは型推論の機能をもつので必ずしも型の宣言が必要というわけではないが、なるべく宣言しておくのが好ましい。</p>
				<pre lang="haskell">
関数名 :: 第1引数の型 -> 第2引数の型 -> ・・・ -> 返り値の型
</pre>
				<h2>高階関数</h2>
				<p>高階関数とは<strong>引数に関数をとる関数</strong>のこと。</p>
				<pre lang="haskell">
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
</pre>
				<p>このプログラムでは5行目で高階関数のmap関数が使われている。map translate csと言うのは、<strong>translate関数そのものにmapを適用しているのであって、translateの結果にmapを適用しているわけではない</strong>。</p>
				<p>mapの型は</p>
				<pre lang="haskell">
map :: (a -> b) -> [a] -> [b]
</pre>
				<p>となっており、<strong>(a -> b)は「a型の値を引数にとりb型の値を返す関数」</strong>を意味する。今回の場合だと、translate関数の型が Char -> Char となっているので、「Char型の値を引数にとりChar型の値を返す関数」と読み替えることができる。更にいうと(a -> b) -> [a] -> [b] は (Char -> Char) -> [Char] -> [Char]となる。</p>
				<pre lang="haskell">
main = do cs < - getContents
          putStr $ expand cs

expand :: String -> String
expand cs = concat $ map expandTab cs

expandTab :: Char -> String
expandTab c = if c == '\t' then "        " else [c]
</pre>
				<p>この辺はちょっとややこしくなってくるが、ちゃんと順に考えていけば問題ない。</p>
				<h2>パターンマッチ(1)</h2>
				<pre lang="haskell">
tabStop = 8

main = do cs < - getContents
          putStr $ expand cs

expand :: String -> String
expand cs = concatMap expandTab cs

expandTab :: Char -> String
expandTab '\t' = replicate tabStop ' '
expandTab c = [c]
</pre>
				<p>個人的にtabStopがグローバル変数みたいでなんか気持ち悪い。定数と考えればいいのかな。まぁ今はとりあえず置いておこう。</p>
				<p>今回のプログラムの最後2行で<strong>パターンマッチ</strong>を使用している。下から2行目が引数が「\t」の時に使われる定義。最後の行は仮引数が使われているので、「どんな値」にもマッチする。<strong>パターンマッチは上に書いたものが優先され、マッチするパターンが無い場合には実行時にエラーが発生する</strong>。</p>
				<pre lang="haskell">
関数名 第1引数のパターン 第2引数のパターン ・・・・ = 定義1
関数名 第1引数のパターン 第2引数のパターン ・・・・ = 定義2
関数名 第1引数のパターン 第2引数のパターン ・・・・ = 定義3
</pre>
				<h2>パターンマッチ(2)</h2>
				<pre lang="haskell">
map :: (a -> b) -> [a] -> [b]
map f []     = []
map f (x:xs) = f x : map f xs
</pre>
				<p>2行目のパターンマッチは空リストに一致する。つまりmapの第2引数が[]だった場合、必ず[]を返すと言うことになる。</p>
				<p>3行目の(x:xs)もリストに対するパターンで、空リスト以外のリストにマッチする。<strong>リストの最初の要素がxに束縛され、残りの要素がxsに束縛される</strong>。まぁSchemeのcarやcdrみたいなものかな。</p>
				<p>3行目での定義ではまたさらにmapを適用している。つまり、<strong>再帰を用いて処理している</strong>。Haskellには<strong>ループを扱う構文は存在しない</strong>為である。</p>
				<pre lang="haskell">
map length ["abc", "de", "f"]
  length "abc" : map length ["de", "f"]
    length "de" : map length ["f"]
      length "f" : map length []
      (1 : [])
    (2 : [1])
  (3:[2,1])
[3, 2, 1]
</pre>
				<p>例えば「map length [&#8220;abc&#8221;, &#8220;de&#8221;, &#8220;f&#8221;」だと多分こんな感じ。<strong>「:」演算子はリストを生成する演算子で(y:ys)ならリストysの先頭に要素yを追加する</strong>。</p>
				<h2>練習問題</h2>
				<pre lang="haskell">
main = do cs < - getContents
          putStr $ swapa cs

swapa :: String -> String
swapa cs = map replaceA cs

replaceA :: Char -> Char
replaceA 'a' = 'A'
replaceA 'A' = 'a'
replaceA c = c
</pre>
				<p>とりあえず動く。</p>
				<h2>追記(08/02/27)</h2>
				<pre lang="haskell">
main = do cs < - getContents
          putStr $ map swapa cs

swapa :: Char -> Char
swapa 'a' = 'A'
swapa 'A' = 'a'
swapa c = c
</pre>
				<p>書き直した。この方が短い。</p>
				<div class='wpfblike' style='height: 40px;'><fb:like href='http://ukstudio.jp/2008/02/27/haskell_sec3/' layout='default' show_faces='true' width='400' action='like' colorscheme='light' send='false' /></div>
]]></content:encoded>
			<wfw:commentRss>http://ukstudio.jp/2008/02/27/haskell_sec3/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>ふつケル第2章</title>
		<link>http://ukstudio.jp/2008/02/25/haskell_sec2/</link>
		<comments>http://ukstudio.jp/2008/02/25/haskell_sec2/#comments</comments>
		<pubDate>Mon, 25 Feb 2008 14:24:23 +0000</pubDate>
		<dc:creator>ukstudio</dc:creator>
				<category><![CDATA[article]]></category>
		<category><![CDATA[Haskell]]></category>

		<guid isPermaLink="false">http://ukstudio.sakura.ne.jp/2008/02/25/haskell_sec2/</guid>
		<description><![CDATA[ハロー、ワールド main = putStrLn "Hello, World!" 「main = 」は変数mainの定義. 「putStrLn &#8220;Hello, World!&#8221;」が変数mainの値となる。putStrLnは標準出力に文字列と開業を出力する時に使う関数で、正確に言うと文字列を1つ受けとり、その文字列と改行を出力するアクションを返す関数. 「putStrLn &#8220;Hello, World!&#8221;」の式を、Haskellでは&#8220;Hello,World!&#8221;にputStrLn関数を適用すると言うらしいけど、今一ピンとこないな. 普段Rubyやってるからかな. putStrLn関数を&#8221;Hello,World!&#8221;にあてはめて用いると言いなおせばまだわかるかな. ・・・あんまり変わらないか. cat main = do cs < - getContents putStr cs 1行目のcs < - getContentsとputStr csの2つの式が揃っているのには意味があるらしい。インデントに意味があるなんてPythonみたいなやつだ。複数の式のインデントを揃えることで、do式で1つのブロックに束ねることができる。この規則をレイアウトやオフサイドルールと言う。複数のアクションをdo式でまとめると上から下へ実行されることが保証される。 アクションの結果を得るときに「< -」を使う。このサンプルの場合だと、getContentsアクションで入力した文字列が変数csに結びつき、それを「変数を値(アクションの結果)に束縛する(bind)」と言う。値が変数を束縛するのか。値は寂しがりやさんだな。 このサンプルには遅延評価も関連してるが、ここではあまり詳しく触れてないのでスルー。 countline main = do cs < - getContents print $ length $ lines cs Haskellにおいてリストはかなり重要。Haskellでは文字列もリストとなっている。リストには一種類の値しか入れられない。このあたりはRuby、JavaScriptあたりをやっていると忘れがちなので注意。 ['a', 'b', 'c'] => [...]]]></description>
			<content:encoded><![CDATA[				<div class='wpfblike' style='height: 40px;'><fb:like href='http://ukstudio.jp/2008/02/25/haskell_sec2/' layout='default' show_faces='true' width='400' action='like' colorscheme='light' send='false' /></div><h2>ハロー、ワールド</h2>
				<pre lang="haskell">
main = putStrLn "Hello, World!"
</pre>
				<p>「main = 」は変数mainの定義. 「putStrLn &#8220;Hello, World!&#8221;」が変数mainの値となる。putStrLnは標準出力に文字列と開業を出力する時に使う関数で、正確に言うと<strong>文字列を1つ受けとり、その文字列と改行を出力するアクションを返す関数</strong>.</p>
				<p>「putStrLn &#8220;Hello, World!&#8221;」の式を、Haskellでは<strong>&#8220;Hello,World!&#8221;にputStrLn関数を適用する</strong>と言うらしいけど、今一ピンとこないな. 普段Rubyやってるからかな. putStrLn関数を&#8221;Hello,World!&#8221;にあてはめて用いると言いなおせばまだわかるかな. ・・・あんまり変わらないか.</p>
				<h2>cat</h2>
				<pre lang="haskell">
main = do cs < - getContents
          putStr cs
</pre>
				<p>1行目のcs < - getContentsとputStr csの2つの式が揃っているのには意味があるらしい。インデントに意味があるなんてPythonみたいなやつだ。複数の式のインデントを揃えることで、do式で1つのブロックに束ねることができる。この規則をレイアウトやオフサイドルールと言う。<strong>複数のアクションをdo式でまとめると上から下へ実行されることが保証される</strong>。</p>
				<p>アクションの結果を得るときに「< -」を使う。このサンプルの場合だと、getContentsアクションで入力した文字列が変数csに結びつき、それを「<strong>変数を値(アクションの結果)に束縛する(bind)</strong>」と言う。値が変数を束縛するのか。値は寂しがりやさんだな。</p>
				<p>このサンプルには遅延評価も関連してるが、ここではあまり詳しく触れてないのでスルー。</p>
				<h2>countline</h2>
				</pre>
				<pre lang="haskell">
main = do cs < - getContents
          print $ length $ lines cs
</pre>
				<p>Haskellにおいてリストはかなり重要。Haskellでは<strong>文字列もリスト</strong>となっている。リストには<strong>一種類の値しか入れられない</strong>。このあたりはRuby、JavaScriptあたりをやっていると忘れがちなので注意。</p>
				</pre>
				<pre lang="haskell">
['a', 'b', 'c'] => "abc"
[1, 2, 'a'] => NG
</pre>
				<p>$演算子は+や-と同じような二項演算子。ここでは<strong>式を区切る</strong>ために使われている。$を()に置き換えると以下のようになる。</p>
				<pre lang="haskell">
main = do cs < - getContents
          print (length (lines cs))
</pre>
				<h2>head</h2>
				</pre>
				<pre lang="haskell">
main = do cs < - getContents
          putStr $ firstNLines 10 cs

firstNLines n cs = unlines $ take n $ lines cs
</pre>
				<p>4行目のfirstNLinesは関数の定義。基本的にmainの時と同じだけど、今回は仮引数が登場している。nとcsがそれぞれ第1仮引数、第2引数。</p>
				</pre>
				<pre lang="haskell">
関数名 仮引数1 仮引数2・・・ = 関数本体
</pre>
				<h2>tail</h2>
				<pre lang="haskell">
main = do cs < - getContents
          putStr $ lastNLines 10 cs

lastNLines n cs = unlines $ takeLast n $ lines cs
takeLast n ss = reverse $ take n $ reverse ss
</pre>
				<p>今迄に登場したものだけを使っているので、特別なことはなし。</p>
				<h2>練習問題</h2>
				<p>countbyte.hs
				</pre>
				<pre lang="haskell">
main = do cs < - getContents
          print $ length cs
</pre>
				<p>countword.hs
				</pre>
				<pre lang="haskell">
main = do cs < - getContents
          print $ length $ words cs
</pre>
				<p>とりあえずチャチャっと書いてみた。countword.hsは単語数だから問題ないと思うけど、countbyte.hsは日本語の全角文字とかも1byte扱いすると思う。と思ったらちゃんと計算してくれた。でも、ghciで"あ"のlengthをとると1が返ってくる。よくわからん。</p>
				</pre>
				<pre lang="haskell">
Prelude> length "あ"
1
</pre>
				<div class='wpfblike' style='height: 40px;'><fb:like href='http://ukstudio.jp/2008/02/25/haskell_sec2/' layout='default' show_faces='true' width='400' action='like' colorscheme='light' send='false' /></div>
]]></content:encoded>
			<wfw:commentRss>http://ukstudio.jp/2008/02/25/haskell_sec2/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

