Skip to content

Instantly share code, notes, and snippets.

@meganehouser
Last active March 11, 2019 11:00
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save meganehouser/c1ccebfc1a5efeed51fee633f14f8327 to your computer and use it in GitHub Desktop.
Save meganehouser/c1ccebfc1a5efeed51fee633f14f8327 to your computer and use it in GitHub Desktop.
MeguroLYAHFGG#1(すごいHaskell本を原書で読む会 )のノート。@nnm_techさんがまとめたものに実行結果と補足を追加したものです。
Display the source blob
Display the rendered blob
Raw
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# 1. Introduction\n",
"\n",
"[Introduction](https://www.scrible.com/view/source/EKIG0C1102GQ9I7H148180JK8464462V:447091694/)\n",
"\n",
"## About this tutorial\n",
"\n",
"- いろんなサイトに書かれている資料の断片をまとめたものです\n",
"- 命令型プログラミングの経験はあるが、関数型言語の経験がないユーザー向けの資料です\n",
"\n",
"[命令型プログラミング - Wikipedia](https://ja.wikipedia.org/wiki/%E5%91%BD%E4%BB%A4%E5%9E%8B%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9F%E3%83%B3%E3%82%B0)\n",
"\n",
"- Haskellはとても奇妙なように見えて学ぶのつらいけど、最初のハードルを超えたら後は楽です\n",
"- Haskellを学ぶことは初めてプログラムについて学ぶことと似ています、楽しいよ!\n",
"- Haskellによってあなたは異なった考え方をせざるを得なくなる\n",
"\n",
"## So what's Haskell?\n",
"\n",
"Haskellは純粋関数型言語です。\n",
"\n",
"- 純粋関数型言語ではコンピュータに何をするか伝えない。その代わりコンピュータにそれが何なのかを伝える。\n",
"- 純粋関数型言語ではある変数をsetした後、別のなにかに変更することはできないです。\n",
"- [補足] \"純粋な\"関数型言語ではなく、\"純粋関数\"という概念がある。純粋関数は副作用を持たず、参照透過性を持つ\n",
"\n",
"**副作用**\n",
"\n",
"- 純粋関数型において、関数には副作用がない。関数ができる唯一のことは何かを計算し結果を返すことのみ\n",
"- [補足]例えば標準出力への文字出力も副作用である。Haskellではモナドを使って関数の純粋性を保ったままそのような作用を実行する\n",
"\n",
"**参照透過性**\n",
"\n",
"- 関数が同じパラメータで2回呼ばれた場合、同じ結果が返されることを保証\n",
"- コンパイラがプログラムの振る舞いを推論できるようにするだけでなく、関数が正しくそして単純な関数を結合することでより複雑な関数を作ることを簡単に人間が推論(そして証明さえも)できるようになる\n",
"\n",
"命令型言語では一連のタスクを与え実行してもらうことで物事を成し遂げており、実行中は状態が変化可能である。\n",
"\n",
"Haskellは怠け者です。\n",
"\n",
"**遅延評価**\n",
"\n",
"- Haskellは結果を必要とされない限りは関数を実行しそして計算しようとはしない\n",
"- 参照透過性により、プログラムをデータ変換の連続と考えることができる。このHaskellの挙動は参照透過性によりうまく動作する\n",
"\n",
"[遅延評価 - Wikipedia](https://ja.wikipedia.org/wiki/%E9%81%85%E5%BB%B6%E8%A9%95%E4%BE%A1)\n",
"\n",
"- [補足]実際には業務でHaskellを書く場合、遅延評価で面倒なことも多いため、デフォルトの評価戦略を正格評価にする言語拡張が最近のGHC(GHC8.0)に入った。\n",
"\n",
" [さようなら遅延評価 - あどけない話](https://kazu-yamamoto.hatenablog.jp/entry/2019/02/15/115630)\n",
"\n",
"Haskellは静的型付けです。\n",
"\n",
"- コンパイル時にエラーの可能性がある部分をとらえることができる\n",
"- Haskellには **型推論** がある\n",
"\n",
"Haskellはエレガントで簡潔です。\n",
"\n",
"- 命令型プログラミング言語と同等のものを短く書くことができる\n",
"\n",
"Haskellはめっちゃ頭のいい人によって作られました。\n",
"\n",
"## What you need to dive in\n",
"\n",
"- テキストエディタとHaskellコンパイラが必要です。\n",
"- GHCと呼ばれるもっとも広く使われているHaskellコンパイラを使っていきます。\n",
"- [補足]GHCはGlasgow Haskell Compilerの略。グラスゴー大学のKevin Hammondが開発を始めたため。\n",
"\n",
"**GHC**\n",
"\n",
"- Haskell script(.hsのファイル)をコンパイルできます\n",
"- `ghci`というインタラクティブモードも用意されています\n",
"\n",
"[MacでのHaskell環境の構築 - Qiita](https://qiita.com/motokiee/items/4302d3b67798fc526429)\n",
"\n",
"# 2. Starting Out\n",
"\n",
"[Starting Out](https://www.scrible.com/view/source/2KG814151GGU8IIH10O3C1H10G24MG2V:451082089/)\n",
"\n",
"## Ready, set, go!"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### 簡単な計算"
]
},
{
"cell_type": "code",
"execution_count": 1,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"17"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"2 + 15"
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {
"scrolled": true
},
"outputs": [
{
"data": {
"text/plain": [
"4900"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"49 * 100"
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"420"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"1892 - 1472"
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"2.5"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"5 / 2"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"`()`で優先順位を明確にすることができます"
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {
"scrolled": false
},
"outputs": [
{
"data": {
"text/plain": [
"1"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/plain": [
"1"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/plain": [
"-244950"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"(50 * 100) - 4999\n",
"50 * 100 - 4999\n",
"50 * (100 - 4999)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"負数を扱う時は `()`でくくらないとGHCIに怒られます"
]
},
{
"cell_type": "code",
"execution_count": 15,
"metadata": {
"scrolled": false
},
"outputs": [
{
"data": {
"text/plain": [
"-15"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"5 * (-3)"
]
},
{
"cell_type": "code",
"execution_count": 19,
"metadata": {
"scrolled": false
},
"outputs": [
{
"data": {
"text/html": [
"<style>/* Styles used for the Hoogle display in the pager */\n",
".hoogle-doc {\n",
"display: block;\n",
"padding-bottom: 1.3em;\n",
"padding-left: 0.4em;\n",
"}\n",
".hoogle-code {\n",
"display: block;\n",
"font-family: monospace;\n",
"white-space: pre;\n",
"}\n",
".hoogle-text {\n",
"display: block;\n",
"}\n",
".hoogle-name {\n",
"color: green;\n",
"font-weight: bold;\n",
"}\n",
".hoogle-head {\n",
"font-weight: bold;\n",
"}\n",
".hoogle-sub {\n",
"display: block;\n",
"margin-left: 0.4em;\n",
"}\n",
".hoogle-package {\n",
"font-weight: bold;\n",
"font-style: italic;\n",
"}\n",
".hoogle-module {\n",
"font-weight: bold;\n",
"}\n",
".hoogle-class {\n",
"font-weight: bold;\n",
"}\n",
".get-type {\n",
"color: green;\n",
"font-weight: bold;\n",
"font-family: monospace;\n",
"display: block;\n",
"white-space: pre-wrap;\n",
"}\n",
".show-type {\n",
"color: green;\n",
"font-weight: bold;\n",
"font-family: monospace;\n",
"margin-left: 1em;\n",
"}\n",
".mono {\n",
"font-family: monospace;\n",
"display: block;\n",
"}\n",
".err-msg {\n",
"color: red;\n",
"font-style: italic;\n",
"font-family: monospace;\n",
"white-space: pre;\n",
"display: block;\n",
"}\n",
"#unshowable {\n",
"color: red;\n",
"font-weight: bold;\n",
"}\n",
".err-msg.in.collapse {\n",
"padding-top: 0.7em;\n",
"}\n",
".highlight-code {\n",
"white-space: pre;\n",
"font-family: monospace;\n",
"}\n",
".suggestion-warning { \n",
"font-weight: bold;\n",
"color: rgb(200, 130, 0);\n",
"}\n",
".suggestion-error { \n",
"font-weight: bold;\n",
"color: red;\n",
"}\n",
".suggestion-name {\n",
"font-weight: bold;\n",
"}\n",
"</style><span class='err-msg'>&lt;interactive&gt;:1:1: error: Precedence parsing error cannot mix ‘*’ [infixl 7] and prefix `-' [infixl 6] in the same infix expression</span>"
],
"text/plain": [
"<interactive>:1:1: error: Precedence parsing error cannot mix ‘*’ [infixl 7] and prefix `-' [infixl 6] in the same infix expression"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"5 * -3"
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"-15"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"-- これは通る。なぜなのか?\n",
"-5 * 3"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### 論理演算子\n",
"- `boolean`関連のoperator and: `&&`, or: `||`, not: `not`"
]
},
{
"cell_type": "code",
"execution_count": 8,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"<style>/* Styles used for the Hoogle display in the pager */\n",
".hoogle-doc {\n",
"display: block;\n",
"padding-bottom: 1.3em;\n",
"padding-left: 0.4em;\n",
"}\n",
".hoogle-code {\n",
"display: block;\n",
"font-family: monospace;\n",
"white-space: pre;\n",
"}\n",
".hoogle-text {\n",
"display: block;\n",
"}\n",
".hoogle-name {\n",
"color: green;\n",
"font-weight: bold;\n",
"}\n",
".hoogle-head {\n",
"font-weight: bold;\n",
"}\n",
".hoogle-sub {\n",
"display: block;\n",
"margin-left: 0.4em;\n",
"}\n",
".hoogle-package {\n",
"font-weight: bold;\n",
"font-style: italic;\n",
"}\n",
".hoogle-module {\n",
"font-weight: bold;\n",
"}\n",
".hoogle-class {\n",
"font-weight: bold;\n",
"}\n",
".get-type {\n",
"color: green;\n",
"font-weight: bold;\n",
"font-family: monospace;\n",
"display: block;\n",
"white-space: pre-wrap;\n",
"}\n",
".show-type {\n",
"color: green;\n",
"font-weight: bold;\n",
"font-family: monospace;\n",
"margin-left: 1em;\n",
"}\n",
".mono {\n",
"font-family: monospace;\n",
"display: block;\n",
"}\n",
".err-msg {\n",
"color: red;\n",
"font-style: italic;\n",
"font-family: monospace;\n",
"white-space: pre;\n",
"display: block;\n",
"}\n",
"#unshowable {\n",
"color: red;\n",
"font-weight: bold;\n",
"}\n",
".err-msg.in.collapse {\n",
"padding-top: 0.7em;\n",
"}\n",
".highlight-code {\n",
"white-space: pre;\n",
"font-family: monospace;\n",
"}\n",
".suggestion-warning { \n",
"font-weight: bold;\n",
"color: rgb(200, 130, 0);\n",
"}\n",
".suggestion-error { \n",
"font-weight: bold;\n",
"color: red;\n",
"}\n",
".suggestion-name {\n",
"font-weight: bold;\n",
"}\n",
"</style><div class=\"suggestion-name\" style=\"clear:both;\">Evaluate</div><div class=\"suggestion-row\" style=\"float: left;\"><div class=\"suggestion-warning\">Found:</div><div class=\"highlight-code\" id=\"haskell\">True && False</div></div><div class=\"suggestion-row\" style=\"float: left;\"><div class=\"suggestion-warning\">Why Not:</div><div class=\"highlight-code\" id=\"haskell\">False</div></div>"
],
"text/plain": [
"Line 1: Evaluate\n",
"Found:\n",
"True && False\n",
"Why not:\n",
"False"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/plain": [
"False"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"True && False"
]
},
{
"cell_type": "code",
"execution_count": 9,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"<style>/* Styles used for the Hoogle display in the pager */\n",
".hoogle-doc {\n",
"display: block;\n",
"padding-bottom: 1.3em;\n",
"padding-left: 0.4em;\n",
"}\n",
".hoogle-code {\n",
"display: block;\n",
"font-family: monospace;\n",
"white-space: pre;\n",
"}\n",
".hoogle-text {\n",
"display: block;\n",
"}\n",
".hoogle-name {\n",
"color: green;\n",
"font-weight: bold;\n",
"}\n",
".hoogle-head {\n",
"font-weight: bold;\n",
"}\n",
".hoogle-sub {\n",
"display: block;\n",
"margin-left: 0.4em;\n",
"}\n",
".hoogle-package {\n",
"font-weight: bold;\n",
"font-style: italic;\n",
"}\n",
".hoogle-module {\n",
"font-weight: bold;\n",
"}\n",
".hoogle-class {\n",
"font-weight: bold;\n",
"}\n",
".get-type {\n",
"color: green;\n",
"font-weight: bold;\n",
"font-family: monospace;\n",
"display: block;\n",
"white-space: pre-wrap;\n",
"}\n",
".show-type {\n",
"color: green;\n",
"font-weight: bold;\n",
"font-family: monospace;\n",
"margin-left: 1em;\n",
"}\n",
".mono {\n",
"font-family: monospace;\n",
"display: block;\n",
"}\n",
".err-msg {\n",
"color: red;\n",
"font-style: italic;\n",
"font-family: monospace;\n",
"white-space: pre;\n",
"display: block;\n",
"}\n",
"#unshowable {\n",
"color: red;\n",
"font-weight: bold;\n",
"}\n",
".err-msg.in.collapse {\n",
"padding-top: 0.7em;\n",
"}\n",
".highlight-code {\n",
"white-space: pre;\n",
"font-family: monospace;\n",
"}\n",
".suggestion-warning { \n",
"font-weight: bold;\n",
"color: rgb(200, 130, 0);\n",
"}\n",
".suggestion-error { \n",
"font-weight: bold;\n",
"color: red;\n",
"}\n",
".suggestion-name {\n",
"font-weight: bold;\n",
"}\n",
"</style><div class=\"suggestion-name\" style=\"clear:both;\">Evaluate</div><div class=\"suggestion-row\" style=\"float: left;\"><div class=\"suggestion-warning\">Found:</div><div class=\"highlight-code\" id=\"haskell\">True && True</div></div><div class=\"suggestion-row\" style=\"float: left;\"><div class=\"suggestion-warning\">Why Not:</div><div class=\"highlight-code\" id=\"haskell\">True</div></div>"
],
"text/plain": [
"Line 1: Evaluate\n",
"Found:\n",
"True && True\n",
"Why not:\n",
"True"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/plain": [
"True"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"True && True"
]
},
{
"cell_type": "code",
"execution_count": 10,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"<style>/* Styles used for the Hoogle display in the pager */\n",
".hoogle-doc {\n",
"display: block;\n",
"padding-bottom: 1.3em;\n",
"padding-left: 0.4em;\n",
"}\n",
".hoogle-code {\n",
"display: block;\n",
"font-family: monospace;\n",
"white-space: pre;\n",
"}\n",
".hoogle-text {\n",
"display: block;\n",
"}\n",
".hoogle-name {\n",
"color: green;\n",
"font-weight: bold;\n",
"}\n",
".hoogle-head {\n",
"font-weight: bold;\n",
"}\n",
".hoogle-sub {\n",
"display: block;\n",
"margin-left: 0.4em;\n",
"}\n",
".hoogle-package {\n",
"font-weight: bold;\n",
"font-style: italic;\n",
"}\n",
".hoogle-module {\n",
"font-weight: bold;\n",
"}\n",
".hoogle-class {\n",
"font-weight: bold;\n",
"}\n",
".get-type {\n",
"color: green;\n",
"font-weight: bold;\n",
"font-family: monospace;\n",
"display: block;\n",
"white-space: pre-wrap;\n",
"}\n",
".show-type {\n",
"color: green;\n",
"font-weight: bold;\n",
"font-family: monospace;\n",
"margin-left: 1em;\n",
"}\n",
".mono {\n",
"font-family: monospace;\n",
"display: block;\n",
"}\n",
".err-msg {\n",
"color: red;\n",
"font-style: italic;\n",
"font-family: monospace;\n",
"white-space: pre;\n",
"display: block;\n",
"}\n",
"#unshowable {\n",
"color: red;\n",
"font-weight: bold;\n",
"}\n",
".err-msg.in.collapse {\n",
"padding-top: 0.7em;\n",
"}\n",
".highlight-code {\n",
"white-space: pre;\n",
"font-family: monospace;\n",
"}\n",
".suggestion-warning { \n",
"font-weight: bold;\n",
"color: rgb(200, 130, 0);\n",
"}\n",
".suggestion-error { \n",
"font-weight: bold;\n",
"color: red;\n",
"}\n",
".suggestion-name {\n",
"font-weight: bold;\n",
"}\n",
"</style><div class=\"suggestion-name\" style=\"clear:both;\">Evaluate</div><div class=\"suggestion-row\" style=\"float: left;\"><div class=\"suggestion-warning\">Found:</div><div class=\"highlight-code\" id=\"haskell\">False || True</div></div><div class=\"suggestion-row\" style=\"float: left;\"><div class=\"suggestion-warning\">Why Not:</div><div class=\"highlight-code\" id=\"haskell\">True</div></div>"
],
"text/plain": [
"Line 1: Evaluate\n",
"Found:\n",
"False || True\n",
"Why not:\n",
"True"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/plain": [
"True"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"False || True "
]
},
{
"cell_type": "code",
"execution_count": 12,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"<style>/* Styles used for the Hoogle display in the pager */\n",
".hoogle-doc {\n",
"display: block;\n",
"padding-bottom: 1.3em;\n",
"padding-left: 0.4em;\n",
"}\n",
".hoogle-code {\n",
"display: block;\n",
"font-family: monospace;\n",
"white-space: pre;\n",
"}\n",
".hoogle-text {\n",
"display: block;\n",
"}\n",
".hoogle-name {\n",
"color: green;\n",
"font-weight: bold;\n",
"}\n",
".hoogle-head {\n",
"font-weight: bold;\n",
"}\n",
".hoogle-sub {\n",
"display: block;\n",
"margin-left: 0.4em;\n",
"}\n",
".hoogle-package {\n",
"font-weight: bold;\n",
"font-style: italic;\n",
"}\n",
".hoogle-module {\n",
"font-weight: bold;\n",
"}\n",
".hoogle-class {\n",
"font-weight: bold;\n",
"}\n",
".get-type {\n",
"color: green;\n",
"font-weight: bold;\n",
"font-family: monospace;\n",
"display: block;\n",
"white-space: pre-wrap;\n",
"}\n",
".show-type {\n",
"color: green;\n",
"font-weight: bold;\n",
"font-family: monospace;\n",
"margin-left: 1em;\n",
"}\n",
".mono {\n",
"font-family: monospace;\n",
"display: block;\n",
"}\n",
".err-msg {\n",
"color: red;\n",
"font-style: italic;\n",
"font-family: monospace;\n",
"white-space: pre;\n",
"display: block;\n",
"}\n",
"#unshowable {\n",
"color: red;\n",
"font-weight: bold;\n",
"}\n",
".err-msg.in.collapse {\n",
"padding-top: 0.7em;\n",
"}\n",
".highlight-code {\n",
"white-space: pre;\n",
"font-family: monospace;\n",
"}\n",
".suggestion-warning { \n",
"font-weight: bold;\n",
"color: rgb(200, 130, 0);\n",
"}\n",
".suggestion-error { \n",
"font-weight: bold;\n",
"color: red;\n",
"}\n",
".suggestion-name {\n",
"font-weight: bold;\n",
"}\n",
"</style><div class=\"suggestion-name\" style=\"clear:both;\">Evaluate</div><div class=\"suggestion-row\" style=\"float: left;\"><div class=\"suggestion-warning\">Found:</div><div class=\"highlight-code\" id=\"haskell\">not False</div></div><div class=\"suggestion-row\" style=\"float: left;\"><div class=\"suggestion-warning\">Why Not:</div><div class=\"highlight-code\" id=\"haskell\">True</div></div>"
],
"text/plain": [
"Line 1: Evaluate\n",
"Found:\n",
"not False\n",
"Why not:\n",
"True"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/plain": [
"True"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"not False"
]
},
{
"cell_type": "code",
"execution_count": 21,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"True"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"5 == 5 "
]
},
{
"cell_type": "code",
"execution_count": 22,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"False"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"1 == 0 "
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"`/=`はnot equal、 `x /= y = not (x == y)`"
]
},
{
"cell_type": "code",
"execution_count": 23,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"False"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"5 /= 5 "
]
},
{
"cell_type": "code",
"execution_count": 24,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"True"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"5 /= 4"
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"True"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"\"hello\" == \"hello\"\n",
"-- `''`は1文字のcharacter、 `\"\"`は複数文字(書いていないけど)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"同じ型じゃないと `+`とか `==`したときに怒られちゃうよ\n",
" - ちなみに整数は卑怯なので浮動小数点として振る舞える"
]
},
{
"cell_type": "code",
"execution_count": 6,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"<style>/* Styles used for the Hoogle display in the pager */\n",
".hoogle-doc {\n",
"display: block;\n",
"padding-bottom: 1.3em;\n",
"padding-left: 0.4em;\n",
"}\n",
".hoogle-code {\n",
"display: block;\n",
"font-family: monospace;\n",
"white-space: pre;\n",
"}\n",
".hoogle-text {\n",
"display: block;\n",
"}\n",
".hoogle-name {\n",
"color: green;\n",
"font-weight: bold;\n",
"}\n",
".hoogle-head {\n",
"font-weight: bold;\n",
"}\n",
".hoogle-sub {\n",
"display: block;\n",
"margin-left: 0.4em;\n",
"}\n",
".hoogle-package {\n",
"font-weight: bold;\n",
"font-style: italic;\n",
"}\n",
".hoogle-module {\n",
"font-weight: bold;\n",
"}\n",
".hoogle-class {\n",
"font-weight: bold;\n",
"}\n",
".get-type {\n",
"color: green;\n",
"font-weight: bold;\n",
"font-family: monospace;\n",
"display: block;\n",
"white-space: pre-wrap;\n",
"}\n",
".show-type {\n",
"color: green;\n",
"font-weight: bold;\n",
"font-family: monospace;\n",
"margin-left: 1em;\n",
"}\n",
".mono {\n",
"font-family: monospace;\n",
"display: block;\n",
"}\n",
".err-msg {\n",
"color: red;\n",
"font-style: italic;\n",
"font-family: monospace;\n",
"white-space: pre;\n",
"display: block;\n",
"}\n",
"#unshowable {\n",
"color: red;\n",
"font-weight: bold;\n",
"}\n",
".err-msg.in.collapse {\n",
"padding-top: 0.7em;\n",
"}\n",
".highlight-code {\n",
"white-space: pre;\n",
"font-family: monospace;\n",
"}\n",
".suggestion-warning { \n",
"font-weight: bold;\n",
"color: rgb(200, 130, 0);\n",
"}\n",
".suggestion-error { \n",
"font-weight: bold;\n",
"color: red;\n",
"}\n",
".suggestion-name {\n",
"font-weight: bold;\n",
"}\n",
"</style><span class='err-msg'>&lt;interactive&gt;:1:1: error:<br/> • No instance for (Num Bool) arising from the literal ‘5’<br/> • In the first argument of ‘(==)’, namely ‘5’<br/> In the expression: 5 == True<br/> In an equation for ‘it’: it = 5 == True</span>"
],
"text/plain": [
"<interactive>:1:1: error:\n",
" • No instance for (Num Bool) arising from the literal ‘5’\n",
" • In the first argument of ‘(==)’, namely ‘5’\n",
" In the expression: 5 == True\n",
" In an equation for ‘it’: it = 5 == True"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
" 5 == True"
]
},
{
"cell_type": "code",
"execution_count": 7,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"9.0"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
" 5 + 4.0"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### 関数\n",
"- Haskellでは以下のように関数を呼び出す\n",
" - パラメータを `()`の中で記述する必要はなく、スペースを挿入する\n",
" - 複数のパラメータがあった際、 `,`で区切らずスペースで区切る\n",
"- 関数の実行が一番優先度が高い\n",
"- 関数が2つの引数を取る場合、バッククオートを用いて *infix* functionとして呼ぶことができる\n",
"- `bar (bar 3)`はCでいうところの `bar(bar(3))`"
]
},
{
"cell_type": "code",
"execution_count": 27,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"9"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"succ 8"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"参考:\n",
"\n",
"`succ`(successor functionについて)\n",
"\n",
"[後者関数 - Wikipedia](https://ja.wikipedia.org/wiki/%E5%BE%8C%E8%80%85%E9%96%A2%E6%95%B0)\n",
"\n",
"[原始再帰関数 - Wikipedia](https://ja.wikipedia.org/wiki/%E5%8E%9F%E5%A7%8B%E5%86%8D%E5%B8%B0%E9%96%A2%E6%95%B0)\n",
"\n",
"[再帰理論 - Wikipedia](https://ja.wikipedia.org/wiki/%E5%86%8D%E5%B8%B0%E7%90%86%E8%AB%96)\n",
"\n",
"- [補足]Haskellで関数のヘルプを見たり、関数を探したい場合どうするか\n",
"\n",
" Hoogleで検索する。Haskellerはよく関数の型でふんわり欲しい関数を検索するらしい\n",
"\n",
" [Hoogle](https://www.haskell.org/hoogle/)\n",
"\n",
" 検索結果からはHackageに跳んで詳細が観れる。(Pythonで言う所のPyPI)"
]
},
{
"cell_type": "code",
"execution_count": 28,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"9"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"min 9 10"
]
},
{
"cell_type": "code",
"execution_count": 29,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"3.2"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"min 3.4 3.2"
]
},
{
"cell_type": "code",
"execution_count": 30,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"101"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"max 100 101"
]
},
{
"cell_type": "code",
"execution_count": 31,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"16"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"succ 9 + max 5 4 + 1"
]
},
{
"cell_type": "code",
"execution_count": 32,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"<style>/* Styles used for the Hoogle display in the pager */\n",
".hoogle-doc {\n",
"display: block;\n",
"padding-bottom: 1.3em;\n",
"padding-left: 0.4em;\n",
"}\n",
".hoogle-code {\n",
"display: block;\n",
"font-family: monospace;\n",
"white-space: pre;\n",
"}\n",
".hoogle-text {\n",
"display: block;\n",
"}\n",
".hoogle-name {\n",
"color: green;\n",
"font-weight: bold;\n",
"}\n",
".hoogle-head {\n",
"font-weight: bold;\n",
"}\n",
".hoogle-sub {\n",
"display: block;\n",
"margin-left: 0.4em;\n",
"}\n",
".hoogle-package {\n",
"font-weight: bold;\n",
"font-style: italic;\n",
"}\n",
".hoogle-module {\n",
"font-weight: bold;\n",
"}\n",
".hoogle-class {\n",
"font-weight: bold;\n",
"}\n",
".get-type {\n",
"color: green;\n",
"font-weight: bold;\n",
"font-family: monospace;\n",
"display: block;\n",
"white-space: pre-wrap;\n",
"}\n",
".show-type {\n",
"color: green;\n",
"font-weight: bold;\n",
"font-family: monospace;\n",
"margin-left: 1em;\n",
"}\n",
".mono {\n",
"font-family: monospace;\n",
"display: block;\n",
"}\n",
".err-msg {\n",
"color: red;\n",
"font-style: italic;\n",
"font-family: monospace;\n",
"white-space: pre;\n",
"display: block;\n",
"}\n",
"#unshowable {\n",
"color: red;\n",
"font-weight: bold;\n",
"}\n",
".err-msg.in.collapse {\n",
"padding-top: 0.7em;\n",
"}\n",
".highlight-code {\n",
"white-space: pre;\n",
"font-family: monospace;\n",
"}\n",
".suggestion-warning { \n",
"font-weight: bold;\n",
"color: rgb(200, 130, 0);\n",
"}\n",
".suggestion-error { \n",
"font-weight: bold;\n",
"color: red;\n",
"}\n",
".suggestion-name {\n",
"font-weight: bold;\n",
"}\n",
"</style><div class=\"suggestion-name\" style=\"clear:both;\">Redundant bracket</div><div class=\"suggestion-row\" style=\"float: left;\"><div class=\"suggestion-warning\">Found:</div><div class=\"highlight-code\" id=\"haskell\">(succ 9) + (max 5 4)</div></div><div class=\"suggestion-row\" style=\"float: left;\"><div class=\"suggestion-warning\">Why Not:</div><div class=\"highlight-code\" id=\"haskell\">succ 9 + (max 5 4)</div></div><div class=\"suggestion-name\" style=\"clear:both;\">Redundant bracket</div><div class=\"suggestion-row\" style=\"float: left;\"><div class=\"suggestion-warning\">Found:</div><div class=\"highlight-code\" id=\"haskell\">(succ 9) + (max 5 4)</div></div><div class=\"suggestion-row\" style=\"float: left;\"><div class=\"suggestion-warning\">Why Not:</div><div class=\"highlight-code\" id=\"haskell\">(succ 9) + max 5 4</div></div>"
],
"text/plain": [
"Line 1: Redundant bracket\n",
"Found:\n",
"(succ 9) + (max 5 4)\n",
"Why not:\n",
"succ 9 + (max 5 4)Line 1: Redundant bracket\n",
"Found:\n",
"(succ 9) + (max 5 4)\n",
"Why not:\n",
"(succ 9) + max 5 4"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/plain": [
"16"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"(succ 9) + (max 5 4) + 1"
]
},
{
"cell_type": "code",
"execution_count": 34,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"9"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"div 92 10"
]
},
{
"cell_type": "code",
"execution_count": 35,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"9"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"92 `div` 10 "
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Baby's first functions\n",
"\n",
"- 関数定義: `関数名 引数 = 処理`\n",
"- Haskellは関数定義の記述順序は関係ない"
]
},
{
"cell_type": "code",
"execution_count": 36,
"metadata": {},
"outputs": [],
"source": [
"doubleMe x = x + x"
]
},
{
"cell_type": "code",
"execution_count": 37,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"18"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"doubleMe 9"
]
},
{
"cell_type": "code",
"execution_count": 38,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"16.6"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"doubleMe 8.3"
]
},
{
"cell_type": "code",
"execution_count": 39,
"metadata": {},
"outputs": [],
"source": [
"doubleUs x y = x*2 + y*2"
]
},
{
"cell_type": "code",
"execution_count": 40,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"26"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"doubleUs 4 9"
]
},
{
"cell_type": "code",
"execution_count": 41,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"73.0"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"doubleUs 2.3 34.2"
]
},
{
"cell_type": "code",
"execution_count": 43,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"478"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"doubleUs 28 88 + doubleMe 123"
]
},
{
"cell_type": "code",
"execution_count": 44,
"metadata": {},
"outputs": [],
"source": [
"doubleUs x y = doubleMe x + doubleMe y"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"#### if式\n",
"\n",
"- elseの記述が義務付けられている\n",
"- Haskellでは全てのexpression(式)や関数は必ず何かを返す必要がある\n",
" - `if`文はexpression\n",
" - `5`は5を返すexpression\n",
" - `4+8`はexpression\n",
" - `x+y`はexpression"
]
},
{
"cell_type": "code",
"execution_count": 45,
"metadata": {},
"outputs": [],
"source": [
"doubleSmallNumber x = if x > 100 \n",
" then x \n",
" else x*2"
]
},
{
"cell_type": "code",
"execution_count": 47,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"101"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/plain": [
"200"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"doubleSmallNumber 101\n",
"doubleSmallNumber 100"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"#### 関数名につく「'」\n",
"\n",
"- Haskellのsyntaxでは特別な意味をもっていないので、関数名に使える\n",
"- 関数名の最後に「'」を付与するときは以下のどれか\n",
" 1. 関数がstrict(正格) version(lazyでない)ことを意味している\n",
" 2. 「'」がついていない関数 or 変数の少し変更されたバージョンである"
]
},
{
"cell_type": "code",
"execution_count": 48,
"metadata": {},
"outputs": [],
"source": [
"doubleSmallNumber' x = (if x > 100 then x else x*2) + 1"
]
},
{
"cell_type": "code",
"execution_count": 49,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"102"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/plain": [
"201"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"doubleSmallNumber' 101\n",
"doubleSmallNumber' 100"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"**命名規則**\n",
"\n",
"- 先頭は小文字\n",
"- 変数がない関数のことをdefinition もしくは nameと呼ぶ。"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": []
}
],
"metadata": {
"kernelspec": {
"display_name": "Haskell",
"language": "haskell",
"name": "haskell"
},
"language_info": {
"codemirror_mode": "ihaskell",
"file_extension": ".hs",
"name": "haskell",
"pygments_lexer": "Haskell",
"version": "8.6.3"
}
},
"nbformat": 4,
"nbformat_minor": 2
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment