SlideShare ist ein Scribd-Unternehmen logo
1 von 24
Haskellの型安全性の力よ
〜 参照透明編 〜
型の力が欲しいか?
コンパイル時に
バグを弾く力が欲しいか?
僕
●
名前
–
あいや (aiya000)
●
Haskell
●
C#
●
Vim
本スライドについて
●
今回「モナド」は出てこないから
大丈夫だよ。
前提知識
●
参照透明性 (「純粋である」とは)
●
純粋でないことの問題点
参照透明性
●
同じ引数で関数を呼び出すと
いつでもどこでも同じ結果が返ってくる
性質のこと
x :: Int
x = 1
f :: Int → Int
f y = x + y
f 10 – => 11
f 1 – => 2
f 10 – => 11
参照透明性
●
参照透明でない反例 (JavaScript)
●
xへの再代入という副作用を持つ
–
副作用を持つ → 参照透明でないことが多い
let x = 1;
const f = y => x++ + y;
f(10) //=> 11
f(1) //=> 3
f(10) //=> 13
参照透明性
●
参照透明でない反例 (JavaScript)
●
xへの再代入という副作用を持つ
–
副作用を持つ → 参照透明でないことが多い
let x = 1;
const f = y => x++ + y;
f(10) //=> 11
f(1) //=> 3
f(10) //=> 13
だいたい逆のこと
参照透明 <> 副作用
画面への出力や
キーボードからの入力なども
副作用になる
(外界へのアクセス)
参照透明性
●
これも副作用 (標準出力)
const f = () => console.log("ahoge");
純粋でないことの問題点
●
グローバル変数やフィールドの値が
どこかの関数に勝手に変更されて
期待してない値が返ってくる
–
=> バグを生み出す
純粋でないことの問題点
●
Haskellなら型レベルで参照透明性を
保証できる
●
型レベル
–
副作用を扱わない型の関数で副作用を扱うと
コンパイルエラーになる
●
型レベルで参照透明を保証できると
限りなくバグが少なくなる
型の力
●
様々な副作用を扱うIO型
●
変数への再代入と加工を扱うIORef型
型の力
●
副作用を伴う関数は必ずIO型
(もしくは同系列の型)を型として持つ
●
main :: IO ()
–
HaskellのEntryPoint
●
getLine :: IO String
–
標準入力を受け取る関数
●
putStrLn :: String → IO ()
–
文字列を標準出力に出力する関数
型の力
●
JavaScriptの例と似たようなやつ
import Data.IORef
action :: IO ()
action = do
x <- newIORef 1
a <- f x 10 – 11
b <- f x 1 – 3
c <- f x 10 – 13
return ()
f :: IORef Int -> Int -> IO Int
f x y = do
current <- readIORef x
modifyIORef x (+1) – 副作用
return $ current + y
import Data.IORef
action :: IO ()
action = do
x <- newIORef 1
a <- f x 10 – 11
b <- f x 1 – 3
c <- f x 10 – 13
return ()
f :: IORef Int -> Int -> IO Int
f x y = do
current <- readIORef x
modifyIORef x (+1) – 副作用
return $ current + y
型の力
●
JavaScriptの例と似たようなやつf x 10
同じ呼び出しで違う戻り値
これはIO型の
副作用によるもの
import Data.IORef
action :: ()
action = do
x <- newIORef 1
a <- f x 10
b <- f x 1
c <- f x 10
return ()
f :: Int -> Int -> Int
f x y = do
current <- readIORef x
modifyIORef x (+1)
return $ current + y
型の力
●
JavaScriptの例と似たようなやつ
関数のIO …を消すと ?
型の力
●
副作用がないはずの型の関数に
副作用が含まれているので
コンパイルエラー
型の力
●
副作用がないはずの型の関数に
副作用が含まれているので
コンパイルエラー
Program.hs:4:1:
Couldn't match expected type ‘IO t3’ with actual type ‘()’
In the expression: main
When checking the type of the IO action ‘main’
型の力
●
副作用がないはずの型の関数に
副作用が含まれているので
コンパイルエラー
Program.hs:4:1:
Couldn't match expected type ‘IO t3’ with actual type ‘()’
In the expression: main
When checking the type of the IO action ‘main’
Program.hs:5:3:
Couldn't match type ‘IO ()’ with ‘()’
Expected type: IO (IORef Integer) -> (IORef Integer -> IO
()) -> ()
Actual type: IO (IORef Integer)
-> (IORef Integer -> IO ()) -> IO ()
In a stmt of a 'do' block: x <- newIORef 1
In the expression:
do { x <- newIORef 1;
a <- f x 10;
b <- f x 1;
c <- f x 10;
型の力
●
副作用がないはずの型の関数に
副作用が含まれているので
コンパイルエラー
Program.hs:4:1:
Couldn't match expected type ‘IO t3’ with actual type ‘()’
In the expression: main
When checking the type of the IO action ‘main’
Program.hs:5:3:
Couldn't match type ‘IO ()’ with ‘()’
Expected type: IO (IORef Integer) -> (IORef Integer -> IO
()) -> ()
Actual type: IO (IORef Integer)
-> (IORef Integer -> IO ()) -> IO ()
In a stmt of a 'do' block: x <- newIORef 1
In the expression:
do { x <- newIORef 1;
a <- f x 10;
b <- f x 1;
c <- f x 10;
Program.hs:6:8:
Couldn't match expected type ‘IO t0’ with actual type ‘In
In a stmt of a 'do' block: a <- f x 10
In the expression:
do { x <- newIORef 1;
a <- f x 10;
b <- f x 1;
c <- f x 10;
.... }
型の力
●
副作用がないはずの型の関数に
副作用が含まれているので
コンパイルエラー
Program.hs:4:1:
Couldn't match expected type ‘IO t3’ with actual type ‘()’
In the expression: main
When checking the type of the IO action ‘main’
Program.hs:5:3:
Couldn't match type ‘IO ()’ with ‘()’
Expected type: IO (IORef Integer) -> (IORef Integer -> IO
()) -> ()
Actual type: IO (IORef Integer)
-> (IORef Integer -> IO ()) -> IO ()
In a stmt of a 'do' block: x <- newIORef 1
In the expression:
do { x <- newIORef 1;
a <- f x 10;
b <- f x 1;
c <- f x 10;
Program.hs:6:8:
Couldn't match expected type ‘IO t0’ with actual type ‘In
In a stmt of a 'do' block: a <- f x 10
In the expression:
do { x <- newIORef 1;
a <- f x 10;
b <- f x 1;
c <- f x 10;
.... }
Program.hs:7:10:
Couldn't match expected type ‘Int’ with actual type ‘IORef
Integer’
In the first argument of ‘f’, namely ‘x’
In a stmt of a 'do' block: b <- f x 1
Program.hs:8:8:
Couldn't match expected type ‘IO t2’ with actual type ‘Int’
In a stmt of a 'do' block: c <- f x 10
In the expression:
do { x <- newIORef 1;
a <- f x 10;
b <- f x 1;
c <- f x 10;
>> Too many compile error <<
まとめ
●
Haskellでは
手続きも値も全て
型によって制御されることになる
●
さもなくば
コンパイルエラーをくらえ
まとめ
●
今回はIOの例に限っており
型による制御能力はこの限りではない
全然この限りではない
–
Maybe (null可能)
–
Writer (ログ付き計算)
–
Reader (環境付き計算)
–
State (状態付き計算)
–
StateT (状態付き計算 + α)
End
イカ、質問よろしく〜

Weitere ähnliche Inhalte

Was ist angesagt?

メタプログラミングRubyはこの付録が美味しい
メタプログラミングRubyはこの付録が美味しいメタプログラミングRubyはこの付録が美味しい
メタプログラミングRubyはこの付録が美味しいShigeru UCHIYAMA
 
WWDC 旅行の余談と Swift Open Hours 3 - Swift ラボで聞いてきた話 #cocoa_kansai
WWDC 旅行の余談と Swift Open Hours 3 - Swift ラボで聞いてきた話 #cocoa_kansaiWWDC 旅行の余談と Swift Open Hours 3 - Swift ラボで聞いてきた話 #cocoa_kansai
WWDC 旅行の余談と Swift Open Hours 3 - Swift ラボで聞いてきた話 #cocoa_kansaiTomohiro Kumagai
 
error handling using expected
error handling using expectederror handling using expected
error handling using expectedAkira Takahashi
 
C++コンパイラ GCCとClangからのメッセージをお読みください
C++コンパイラ GCCとClangからのメッセージをお読みくださいC++コンパイラ GCCとClangからのメッセージをお読みください
C++コンパイラ GCCとClangからのメッセージをお読みくださいdigitalghost
 
ナウなヤングにバカうけのイカしたタグ付き共用体
ナウなヤングにバカうけのイカしたタグ付き共用体ナウなヤングにバカうけのイカしたタグ付き共用体
ナウなヤングにバカうけのイカしたタグ付き共用体digitalghost
 
リテラルと型の話 #__swift__
リテラルと型の話 #__swift__リテラルと型の話 #__swift__
リテラルと型の話 #__swift__Tomohiro Kumagai
 
Scalaでの例外処理
Scalaでの例外処理Scalaでの例外処理
Scalaでの例外処理Takashi Kawachi
 
JavaのGenericsとは?
JavaのGenericsとは?JavaのGenericsとは?
JavaのGenericsとは?Kenji Nakamura
 
90分間濃縮 PHPエラーの教室
90分間濃縮 PHPエラーの教室90分間濃縮 PHPエラーの教室
90分間濃縮 PHPエラーの教室Yusuke Ando
 
知って得するC#
知って得するC#知って得するC#
知って得するC#Shota Baba
 
ちょっと詳しくJavaScript 第2回【関数と引数】
ちょっと詳しくJavaScript 第2回【関数と引数】ちょっと詳しくJavaScript 第2回【関数と引数】
ちょっと詳しくJavaScript 第2回【関数と引数】株式会社ランチェスター
 
ちょっと詳しくJavaScript 第4回【スコープとクロージャ】
ちょっと詳しくJavaScript 第4回【スコープとクロージャ】ちょっと詳しくJavaScript 第4回【スコープとクロージャ】
ちょっと詳しくJavaScript 第4回【スコープとクロージャ】株式会社ランチェスター
 
20120422i phonedeveloperworkshoppublished
20120422i phonedeveloperworkshoppublished20120422i phonedeveloperworkshoppublished
20120422i phonedeveloperworkshoppublishedYoichiro Sakurai
 
ジェネリクスの基礎と クラス設計への応用
ジェネリクスの基礎とクラス設計への応用ジェネリクスの基礎とクラス設計への応用
ジェネリクスの基礎と クラス設計への応用nagise
 
Swift 2.0 で変わったところ「前編」 #cswift
Swift 2.0 で変わったところ「前編」 #cswiftSwift 2.0 で変わったところ「前編」 #cswift
Swift 2.0 で変わったところ「前編」 #cswiftTomohiro Kumagai
 

Was ist angesagt? (20)

メタプログラミングRubyはこの付録が美味しい
メタプログラミングRubyはこの付録が美味しいメタプログラミングRubyはこの付録が美味しい
メタプログラミングRubyはこの付録が美味しい
 
WWDC 旅行の余談と Swift Open Hours 3 - Swift ラボで聞いてきた話 #cocoa_kansai
WWDC 旅行の余談と Swift Open Hours 3 - Swift ラボで聞いてきた話 #cocoa_kansaiWWDC 旅行の余談と Swift Open Hours 3 - Swift ラボで聞いてきた話 #cocoa_kansai
WWDC 旅行の余談と Swift Open Hours 3 - Swift ラボで聞いてきた話 #cocoa_kansai
 
getstartedc#_1
getstartedc#_1getstartedc#_1
getstartedc#_1
 
error handling using expected
error handling using expectederror handling using expected
error handling using expected
 
What is template
What is templateWhat is template
What is template
 
C++コンパイラ GCCとClangからのメッセージをお読みください
C++コンパイラ GCCとClangからのメッセージをお読みくださいC++コンパイラ GCCとClangからのメッセージをお読みください
C++コンパイラ GCCとClangからのメッセージをお読みください
 
ナウなヤングにバカうけのイカしたタグ付き共用体
ナウなヤングにバカうけのイカしたタグ付き共用体ナウなヤングにバカうけのイカしたタグ付き共用体
ナウなヤングにバカうけのイカしたタグ付き共用体
 
C#6.0の新機能紹介
C#6.0の新機能紹介C#6.0の新機能紹介
C#6.0の新機能紹介
 
リテラルと型の話 #__swift__
リテラルと型の話 #__swift__リテラルと型の話 #__swift__
リテラルと型の話 #__swift__
 
JavaScript入門
JavaScript入門JavaScript入門
JavaScript入門
 
Scalaでの例外処理
Scalaでの例外処理Scalaでの例外処理
Scalaでの例外処理
 
JavaのGenericsとは?
JavaのGenericsとは?JavaのGenericsとは?
JavaのGenericsとは?
 
90分間濃縮 PHPエラーの教室
90分間濃縮 PHPエラーの教室90分間濃縮 PHPエラーの教室
90分間濃縮 PHPエラーの教室
 
知って得するC#
知って得するC#知って得するC#
知って得するC#
 
ちょっと詳しくJavaScript 第2回【関数と引数】
ちょっと詳しくJavaScript 第2回【関数と引数】ちょっと詳しくJavaScript 第2回【関数と引数】
ちょっと詳しくJavaScript 第2回【関数と引数】
 
ちょっと詳しくJavaScript 第4回【スコープとクロージャ】
ちょっと詳しくJavaScript 第4回【スコープとクロージャ】ちょっと詳しくJavaScript 第4回【スコープとクロージャ】
ちょっと詳しくJavaScript 第4回【スコープとクロージャ】
 
20120422i phonedeveloperworkshoppublished
20120422i phonedeveloperworkshoppublished20120422i phonedeveloperworkshoppublished
20120422i phonedeveloperworkshoppublished
 
ジェネリクスの基礎と クラス設計への応用
ジェネリクスの基礎とクラス設計への応用ジェネリクスの基礎とクラス設計への応用
ジェネリクスの基礎と クラス設計への応用
 
Swift 2.0 で変わったところ「前編」 #cswift
Swift 2.0 で変わったところ「前編」 #cswiftSwift 2.0 で変わったところ「前編」 #cswift
Swift 2.0 で変わったところ「前編」 #cswift
 
PHP 入門
PHP 入門PHP 入門
PHP 入門
 

Andere mochten auch

圏論 3分(?) クッキング
圏論 3分(?) クッキング圏論 3分(?) クッキング
圏論 3分(?) クッキングaiya000
 
Vim の開発環境
Vim の開発環境Vim の開発環境
Vim の開発環境eagletmt
 
圏論のおはなし
圏論のおはなし圏論のおはなし
圏論のおはなしTakeo Imai
 
並行プログラミングと継続モナド
並行プログラミングと継続モナド並行プログラミングと継続モナド
並行プログラミングと継続モナドKousuke Ruichi
 
20160702_圏論の基礎
20160702_圏論の基礎20160702_圏論の基礎
20160702_圏論の基礎matsumoring
 
圏論とHaskellは仲良し
圏論とHaskellは仲良し圏論とHaskellは仲良し
圏論とHaskellは仲良しohmori
 
LTS & ローリングリリース! ― ランキング4位のLinuxディストリビューション openSUSE を Azure で使ってみる
LTS & ローリングリリース! ― ランキング4位のLinuxディストリビューション openSUSE を Azure で使ってみるLTS & ローリングリリース! ― ランキング4位のLinuxディストリビューション openSUSE を Azure で使ってみる
LTS & ローリングリリース! ― ランキング4位のLinuxディストリビューション openSUSE を Azure で使ってみるFuminobu Takeyama
 
Haskell Day2012 - 参照透過性とは何だったのか
Haskell Day2012 - 参照透過性とは何だったのかHaskell Day2012 - 参照透過性とは何だったのか
Haskell Day2012 - 参照透過性とは何だったのかKousuke Ruichi
 
すごいVimでhaskellを書こう@なごやまつり
すごいVimでhaskellを書こう@なごやまつりすごいVimでhaskellを書こう@なごやまつり
すごいVimでhaskellを書こう@なごやまつりcohama
 
TypeScriptハンズオン第1回テキスト
TypeScriptハンズオン第1回テキストTypeScriptハンズオン第1回テキスト
TypeScriptハンズオン第1回テキストmizuky fujitani
 
Haskell勉強会 14.1〜14.3 の説明資料
Haskell勉強会 14.1〜14.3 の説明資料Haskell勉強会 14.1〜14.3 の説明資料
Haskell勉強会 14.1〜14.3 の説明資料Etsuji Nakai
 
思いやり駆動開発@XP祭り2007
思いやり駆動開発@XP祭り2007思いやり駆動開発@XP祭り2007
思いやり駆動開発@XP祭り2007Kuniaki Igarashi
 

Andere mochten auch (15)

圏論 3分(?) クッキング
圏論 3分(?) クッキング圏論 3分(?) クッキング
圏論 3分(?) クッキング
 
圏とHaskellの型
圏とHaskellの型圏とHaskellの型
圏とHaskellの型
 
Vim の開発環境
Vim の開発環境Vim の開発環境
Vim の開発環境
 
圏論のおはなし
圏論のおはなし圏論のおはなし
圏論のおはなし
 
並行プログラミングと継続モナド
並行プログラミングと継続モナド並行プログラミングと継続モナド
並行プログラミングと継続モナド
 
20160702_圏論の基礎
20160702_圏論の基礎20160702_圏論の基礎
20160702_圏論の基礎
 
MP in Haskell
MP in HaskellMP in Haskell
MP in Haskell
 
圏論とHaskellは仲良し
圏論とHaskellは仲良し圏論とHaskellは仲良し
圏論とHaskellは仲良し
 
LTS & ローリングリリース! ― ランキング4位のLinuxディストリビューション openSUSE を Azure で使ってみる
LTS & ローリングリリース! ― ランキング4位のLinuxディストリビューション openSUSE を Azure で使ってみるLTS & ローリングリリース! ― ランキング4位のLinuxディストリビューション openSUSE を Azure で使ってみる
LTS & ローリングリリース! ― ランキング4位のLinuxディストリビューション openSUSE を Azure で使ってみる
 
Haskell Day2012 - 参照透過性とは何だったのか
Haskell Day2012 - 参照透過性とは何だったのかHaskell Day2012 - 参照透過性とは何だったのか
Haskell Day2012 - 参照透過性とは何だったのか
 
すごいVimでhaskellを書こう@なごやまつり
すごいVimでhaskellを書こう@なごやまつりすごいVimでhaskellを書こう@なごやまつり
すごいVimでhaskellを書こう@なごやまつり
 
TypeScriptハンズオン第1回テキスト
TypeScriptハンズオン第1回テキストTypeScriptハンズオン第1回テキスト
TypeScriptハンズオン第1回テキスト
 
Haskell勉強会 14.1〜14.3 の説明資料
Haskell勉強会 14.1〜14.3 の説明資料Haskell勉強会 14.1〜14.3 の説明資料
Haskell勉強会 14.1〜14.3 の説明資料
 
思いやり駆動開発@XP祭り2007
思いやり駆動開発@XP祭り2007思いやり駆動開発@XP祭り2007
思いやり駆動開発@XP祭り2007
 
Storm の新機能について @HSCR #hadoopreading
Storm の新機能について @HSCR #hadoopreadingStorm の新機能について @HSCR #hadoopreading
Storm の新機能について @HSCR #hadoopreading
 

Ähnlich wie Haskellの型安全性の力よ〜参照透明性編〜

Clojure programming-chapter-2
Clojure programming-chapter-2Clojure programming-chapter-2
Clojure programming-chapter-2Masao Kato
 
やや関数型を意識した風Elixir/Phoenixご紹介
やや関数型を意識した風Elixir/Phoenixご紹介やや関数型を意識した風Elixir/Phoenixご紹介
やや関数型を意識した風Elixir/Phoenixご紹介fukuoka.ex
 
xv6から始めるSPIN入門
xv6から始めるSPIN入門xv6から始めるSPIN入門
xv6から始めるSPIN入門Ryousei Takano
 
asm.js x emscripten: The foundation of the next level Web games
asm.js x emscripten: The foundation of the next level Web gamesasm.js x emscripten: The foundation of the next level Web games
asm.js x emscripten: The foundation of the next level Web gamesNoritada Shimizu
 
オブジェクト指向入門5
オブジェクト指向入門5オブジェクト指向入門5
オブジェクト指向入門5Kenta Hattori
 
関数型プログラミング in javascript
関数型プログラミング in javascript関数型プログラミング in javascript
関数型プログラミング in javascriptRyuma Tsukano
 
Unity2015_No10_~UGUI&Audio~
Unity2015_No10_~UGUI&Audio~Unity2015_No10_~UGUI&Audio~
Unity2015_No10_~UGUI&Audio~CHY72
 
Elmで始めるFunctional Reactive Programming
Elmで始めるFunctional Reactive Programming Elmで始めるFunctional Reactive Programming
Elmで始めるFunctional Reactive Programming Yasuyuki Maeda
 
関数型言語&形式的手法セミナー(3)
関数型言語&形式的手法セミナー(3)関数型言語&形式的手法セミナー(3)
関数型言語&形式的手法セミナー(3)啓 小笠原
 
今日からできる!簡単 .NET 高速化 Tips
今日からできる!簡単 .NET 高速化 Tips今日からできる!簡単 .NET 高速化 Tips
今日からできる!簡単 .NET 高速化 TipsTakaaki Suzuki
 
JSX / Haxe / TypeScript
JSX / Haxe / TypeScriptJSX / Haxe / TypeScript
JSX / Haxe / TypeScriptbleis tift
 

Ähnlich wie Haskellの型安全性の力よ〜参照透明性編〜 (15)

たのしい関数型
たのしい関数型たのしい関数型
たのしい関数型
 
Clojure programming-chapter-2
Clojure programming-chapter-2Clojure programming-chapter-2
Clojure programming-chapter-2
 
やや関数型を意識した風Elixir/Phoenixご紹介
やや関数型を意識した風Elixir/Phoenixご紹介やや関数型を意識した風Elixir/Phoenixご紹介
やや関数型を意識した風Elixir/Phoenixご紹介
 
xv6から始めるSPIN入門
xv6から始めるSPIN入門xv6から始めるSPIN入門
xv6から始めるSPIN入門
 
asm.js x emscripten: The foundation of the next level Web games
asm.js x emscripten: The foundation of the next level Web gamesasm.js x emscripten: The foundation of the next level Web games
asm.js x emscripten: The foundation of the next level Web games
 
オブジェクト指向入門5
オブジェクト指向入門5オブジェクト指向入門5
オブジェクト指向入門5
 
[xDNCL] 配布資料
[xDNCL] 配布資料[xDNCL] 配布資料
[xDNCL] 配布資料
 
関数型プログラミング in javascript
関数型プログラミング in javascript関数型プログラミング in javascript
関数型プログラミング in javascript
 
大人のお型付け
大人のお型付け大人のお型付け
大人のお型付け
 
講座C入門
講座C入門講座C入門
講座C入門
 
Unity2015_No10_~UGUI&Audio~
Unity2015_No10_~UGUI&Audio~Unity2015_No10_~UGUI&Audio~
Unity2015_No10_~UGUI&Audio~
 
Elmで始めるFunctional Reactive Programming
Elmで始めるFunctional Reactive Programming Elmで始めるFunctional Reactive Programming
Elmで始めるFunctional Reactive Programming
 
関数型言語&形式的手法セミナー(3)
関数型言語&形式的手法セミナー(3)関数型言語&形式的手法セミナー(3)
関数型言語&形式的手法セミナー(3)
 
今日からできる!簡単 .NET 高速化 Tips
今日からできる!簡単 .NET 高速化 Tips今日からできる!簡単 .NET 高速化 Tips
今日からできる!簡単 .NET 高速化 Tips
 
JSX / Haxe / TypeScript
JSX / Haxe / TypeScriptJSX / Haxe / TypeScript
JSX / Haxe / TypeScript
 

Haskellの型安全性の力よ〜参照透明性編〜