SlideShare une entreprise Scribd logo
1  sur  28
Télécharger pour lire hors ligne
Haskell超初心者勉強会 14
すごいHaskell 第12章: モノイド (前編)
今回の内容
•newtype
•Monoid とは
•いろんな Monoid
Monoid ...?
•「二項演算子で結合できるような型」
でもその前に、、
newtype
•「1つの型を取り、それを何かにくるん
で別の型にみせかけたい」
data ZipList a = ZipList { getZipList :: [a] }
newtype ZipList a = ZipList { getZipList :: [a] }
newtype の利点・欠点
• 利点
• 速い。包んだり戻したりの処理を省略。
• 欠点
• 値コンストラクタが1種類だけ
• 値コンストラクタがとれるフィールドが
ひとつだけ
newtypeでの
型クラス導出(deriving)
•deriving で導出出来る
•くるまれている型が導出しようとして
いる型クラスのインスタンスでなけれ
ばならない
newtypeでの
型クラスのインスタンス作成
• タプルをFunctorにしたい
• fmap では f を第一要素に効かせたい
• タプルは型コンストラクタが2つ型を取る
• 1つだけ指定できない (関数は出来たのに)
• newtype で包む
newtype Pair b a = Pair { getPair :: (a, b) }
instance Functor (Pair c) where
fmap f (Pair (x, y)) = Pair (f x, y)
こんな感じ
newtype Pair b a = Pair { getPair :: (a, b) }
instance Functor (Pair c) where
fmap f (Pair (x, y)) = Pair (f x, y)
> getPair $ fmap (*100) (Pair (2, 3))
(200,3)
> getPair $ fmap reverse (Pair (“london”, 3))
("nodnol",3)
newtypeの
パターンマッチ (1)
data CoolBool = CoolBool { getCoolBool :: Bool }
helloMe :: CoolBool -> String
helloMe (CoolBool _) = "Hello"
main = putStrLn $ helloMe undefined
評価するとエラーになる値
ここでエラーが起きる
newtypeの
パターンマッチ (2)
newtype CoolBool = CoolBool {getCoolBool :: Bool}
helloMe :: CoolBool -> String
helloMe (CoolBool _) = "Hello"
main = putStrLn $ helloMe undefined
エラーにならない!
値コンストラクタが1つしか存在しな
いので引数を評価せずマッチできる
type, newtype, dataの
整理
•type -- 型の別名 (実際は同じ型)
•newtype -- 包んだ別の型を作る。値コ
ンストラクタは1つだけ。フィールド1
つだけ。速い。
•data -- 新しい型を作る
type, newtype, dataの
使い所
•type -- 型シグネチャを整理したい。名
が体を表すようにしたい。
•newtype -- 既存型をある型クラスのイ
ンスタンスにしたい。新しい型に包み
たい。
•data -- 新しい型を作りたい
余談: Scala 2.10 で
導入された value class
• 1つの値をwrapする
• コンパイル時は違う型
• 基本的に実行時は型変換されない
• pattern match とかしようとすると
実行時に型変換される
class Wrapper(val underlying: Int)
extends AnyVal {
def foo: Wrapper = new Wrapper(underlying * 19)
}
○ ○ = ○
• (* と 1)、(++ と []) に共通の性質は?
• 関数は引数を2つとる
• 2引数と戻り値の型は等しい
• 相手を変えない特別な値がある(1, [])
• 結合的である (a * b) * c = a * (b * c)
→これが Monoid
Monoid とは
•結合的な二項演算子 と 単位元
•* と 1
•++ と []
•+ と 0
•他にも無数の Monoid
Monoid 型クラス
class Monoid m where
mempty :: m
mappend :: m -> m -> m
mconcat :: [m] -> m
mconcat = foldr mappend mempty
mは具体型
単位元(多相定数)
関数
Monoid則
•プログラマの責任!
1) mempty `mappend` x = x
2) x `mappend` mempty = x
3) (x `mappend` y) `mappend` z =
x `mappend` (y `mappend` z)
ここからいろんな
Monoid を見ていきます
ListはMonoid
x `mappend` y = y `mappend` x
は満たさなくて良い
instance Monoid [a] where
mempty = []
mappend = (++)
Monoid [] ではないことに注意
数をMonoidに
instance Num a => Monoid a where
mempty = 1
mappend = (*)
instance Num a => Monoid a where
mempty = 0
mappend = (+)
でも、こっちも定義したい
いったいどうしたら…
そこで newtype
newtype Product a =
Product { getProduct :: a }
deriving (Eq,Ord,Read,Show,Bounded)
instance Num a => Monoid (Product a) where
mempty = Product 1
Product x `mappend` Product y =
Product (x * y)
> getProduct $ Product 3 `mappend` Product 9
27
Sum も同じように定義されている
AnyとAll
•Boolに対するMonoid
newtype Any =
Any { getAny :: Bool }
deriving (Eq,Ord,Read,Show,Bounded)
instance Monoid Any where
mempty = Any False
Any x `mappend` Any y =
Any (x || y)
Ordering monoid
•Ordering 型。値は LT, EQ, GT
instance Monoid Ordering where
mempty = EQ
LT `mappend` _ = LT
EQ `mappend` y = y
GT `mappend` _ = GT
左優先。ただし左がEQの時は右。
文字列の辞書順と合わせた定義。
長さ比較、
同じ時は辞書順比較
import Data.Monoid
lengthCompare :: String -> String -> Ordering
lengthCompare x y =
(length x `compare` length y)
`mappend` (x `compare` y)
便利!
ほんとに便利...?
Maybe monoid
instance Monoid a => Monoid (Maybe a) where
mempty = Nothing
Nothing `mappend` m = m
m `mappend` Nothing = m
Just m1 `mappend` Just m2 =
Just (m1 `mappend` m2)
中身が Monoid の場合はこんな定義ができる
Maybe monoid
First
newtype First a = First {getFirst :: Maybe a}
deriving (Eq,Ord,Read,Show)
instance Monoid (First a) where
mempty = First Nothing
First (Just x) `mappend` _ = First (Just x)
First Nothing `mappend` x = x
> getFirst . mconcat . map First $
[Nothing, Just 9, Just 10]
Just 9
同様に Last a も定義されている
今日はここまで
•今回の感想:
Monoidにすると何がうれしいのかな?
•次回はMonoidでの畳み込みです。
おたのしみに!
これも面白そう
•独習 Scalaz http://goo.gl/8sXTD7
•

Contenu connexe

Tendances

Rubyの御先祖CLUのお話(原本)
Rubyの御先祖CLUのお話(原本)Rubyの御先祖CLUのお話(原本)
Rubyの御先祖CLUのお話(原本)洋史 東平
 
チーム開発Tip紹介(Objective-C)
チーム開発Tip紹介(Objective-C)チーム開発Tip紹介(Objective-C)
チーム開発Tip紹介(Objective-C)Jaeeun Lee
 
非同期処理の基礎
非同期処理の基礎非同期処理の基礎
非同期処理の基礎信之 岩永
 
Incanterの紹介
Incanterの紹介Incanterの紹介
Incanterの紹介mozk_
 
2016年第二回プレ卒研in山口研
2016年第二回プレ卒研in山口研2016年第二回プレ卒研in山口研
2016年第二回プレ卒研in山口研dmcc2015
 
関数プログラミング入門
関数プログラミング入門関数プログラミング入門
関数プログラミング入門Hideyuki Tanaka
 
Backbone model collection (jscafe 8)
Backbone model collection (jscafe 8)Backbone model collection (jscafe 8)
Backbone model collection (jscafe 8)Ryuma Tsukano
 
たのしい高階関数
たのしい高階関数たのしい高階関数
たのしい高階関数Shinichi Kozake
 
すごいH 第12章モノイド
すごいH 第12章モノイドすごいH 第12章モノイド
すごいH 第12章モノイドShinta Hatatani
 
Rubyによるデータ解析
Rubyによるデータ解析Rubyによるデータ解析
Rubyによるデータ解析Shugo Maeda
 
モナドがいっぱい!
モナドがいっぱい!モナドがいっぱい!
モナドがいっぱい!Kenta Sato
 
関数型言語&形式的手法セミナー(3)
関数型言語&形式的手法セミナー(3)関数型言語&形式的手法セミナー(3)
関数型言語&形式的手法セミナー(3)啓 小笠原
 
kagamicomput201806
kagamicomput201806kagamicomput201806
kagamicomput201806swkagami
 
みんなで Swift 復習会 GO! in 沖縄・発表資料
みんなで Swift 復習会 GO! in 沖縄・発表資料みんなで Swift 復習会 GO! in 沖縄・発表資料
みんなで Swift 復習会 GO! in 沖縄・発表資料Tomohiro Kumagai
 
データとは何か
データとは何かデータとは何か
データとは何かKenta Suzuki
 

Tendances (20)

Cocoa勉強会201208
Cocoa勉強会201208Cocoa勉強会201208
Cocoa勉強会201208
 
Rubyの御先祖CLUのお話(原本)
Rubyの御先祖CLUのお話(原本)Rubyの御先祖CLUのお話(原本)
Rubyの御先祖CLUのお話(原本)
 
チーム開発Tip紹介(Objective-C)
チーム開発Tip紹介(Objective-C)チーム開発Tip紹介(Objective-C)
チーム開発Tip紹介(Objective-C)
 
非同期処理の基礎
非同期処理の基礎非同期処理の基礎
非同期処理の基礎
 
C++ マルチスレッド 入門
C++ マルチスレッド 入門C++ マルチスレッド 入門
C++ マルチスレッド 入門
 
Incanterの紹介
Incanterの紹介Incanterの紹介
Incanterの紹介
 
2016年第二回プレ卒研in山口研
2016年第二回プレ卒研in山口研2016年第二回プレ卒研in山口研
2016年第二回プレ卒研in山口研
 
関数プログラミング入門
関数プログラミング入門関数プログラミング入門
関数プログラミング入門
 
大人のお型付け
大人のお型付け大人のお型付け
大人のお型付け
 
Backbone model collection (jscafe 8)
Backbone model collection (jscafe 8)Backbone model collection (jscafe 8)
Backbone model collection (jscafe 8)
 
たのしい高階関数
たのしい高階関数たのしい高階関数
たのしい高階関数
 
すごいH 第12章モノイド
すごいH 第12章モノイドすごいH 第12章モノイド
すごいH 第12章モノイド
 
Rubyによるデータ解析
Rubyによるデータ解析Rubyによるデータ解析
Rubyによるデータ解析
 
JavaScript入門
JavaScript入門JavaScript入門
JavaScript入門
 
モナドがいっぱい!
モナドがいっぱい!モナドがいっぱい!
モナドがいっぱい!
 
関数型言語&形式的手法セミナー(3)
関数型言語&形式的手法セミナー(3)関数型言語&形式的手法セミナー(3)
関数型言語&形式的手法セミナー(3)
 
kagamicomput201806
kagamicomput201806kagamicomput201806
kagamicomput201806
 
みんなで Swift 復習会 GO! in 沖縄・発表資料
みんなで Swift 復習会 GO! in 沖縄・発表資料みんなで Swift 復習会 GO! in 沖縄・発表資料
みんなで Swift 復習会 GO! in 沖縄・発表資料
 
Pytorch 03
Pytorch 03Pytorch 03
Pytorch 03
 
データとは何か
データとは何かデータとは何か
データとは何か
 

En vedette

Haskell超初心者勉強会11
Haskell超初心者勉強会11Haskell超初心者勉強会11
Haskell超初心者勉強会11Takashi Kawachi
 
Haskell超初心者勉強会17
Haskell超初心者勉強会17Haskell超初心者勉強会17
Haskell超初心者勉強会17Takashi Kawachi
 
Haskell超初心者勉強会20
Haskell超初心者勉強会20Haskell超初心者勉強会20
Haskell超初心者勉強会20Takashi Kawachi
 
Scala稟議の通し方(公開版)
Scala稟議の通し方(公開版)Scala稟議の通し方(公開版)
Scala稟議の通し方(公開版)鉄平 土佐
 
Elastic beanstalk と Docker と Play
Elastic beanstalk と Docker と PlayElastic beanstalk と Docker と Play
Elastic beanstalk と Docker と PlayTakashi Kawachi
 
Scalaでの例外処理
Scalaでの例外処理Scalaでの例外処理
Scalaでの例外処理Takashi Kawachi
 
Scalaのオブジェクトの話
Scalaのオブジェクトの話Scalaのオブジェクトの話
Scalaのオブジェクトの話Yasuyuki Maeda
 
やさしいIteratee入門
やさしいIteratee入門やさしいIteratee入門
やさしいIteratee入門Takashi Kawachi
 

En vedette (8)

Haskell超初心者勉強会11
Haskell超初心者勉強会11Haskell超初心者勉強会11
Haskell超初心者勉強会11
 
Haskell超初心者勉強会17
Haskell超初心者勉強会17Haskell超初心者勉強会17
Haskell超初心者勉強会17
 
Haskell超初心者勉強会20
Haskell超初心者勉強会20Haskell超初心者勉強会20
Haskell超初心者勉強会20
 
Scala稟議の通し方(公開版)
Scala稟議の通し方(公開版)Scala稟議の通し方(公開版)
Scala稟議の通し方(公開版)
 
Elastic beanstalk と Docker と Play
Elastic beanstalk と Docker と PlayElastic beanstalk と Docker と Play
Elastic beanstalk と Docker と Play
 
Scalaでの例外処理
Scalaでの例外処理Scalaでの例外処理
Scalaでの例外処理
 
Scalaのオブジェクトの話
Scalaのオブジェクトの話Scalaのオブジェクトの話
Scalaのオブジェクトの話
 
やさしいIteratee入門
やさしいIteratee入門やさしいIteratee入門
やさしいIteratee入門
 

Similaire à Haskell超初心者勉強会14

Or seminar2011final
Or seminar2011finalOr seminar2011final
Or seminar2011finalMikio Kubo
 
How wonderful to be (statically) typed 〜型が付くってスバラシイ〜
How wonderful to be (statically) typed 〜型が付くってスバラシイ〜How wonderful to be (statically) typed 〜型が付くってスバラシイ〜
How wonderful to be (statically) typed 〜型が付くってスバラシイ〜Hiromi Ishii
 
Scalaプログラミング・マニアックス
Scalaプログラミング・マニアックスScalaプログラミング・マニアックス
Scalaプログラミング・マニアックスTomoharu ASAMI
 
mxnetで頑張る深層学習
mxnetで頑張る深層学習mxnetで頑張る深層学習
mxnetで頑張る深層学習Takashi Kitano
 
Javaはどのように動くのか~スライドでわかるJVMの仕組み
Javaはどのように動くのか~スライドでわかるJVMの仕組みJavaはどのように動くのか~スライドでわかるJVMの仕組み
Javaはどのように動くのか~スライドでわかるJVMの仕組みChihiro Ito
 
Real World OCamlを読んでLispと協調してみた
Real World OCamlを読んでLispと協調してみたReal World OCamlを読んでLispと協調してみた
Real World OCamlを読んでLispと協調してみたblackenedgold
 
Java オブジェクトの内部構造
Java オブジェクトの内部構造Java オブジェクトの内部構造
Java オブジェクトの内部構造Taku Miyakawa
 
怠惰なRubyistへの道 fukuoka rubykaigi01
怠惰なRubyistへの道 fukuoka rubykaigi01怠惰なRubyistへの道 fukuoka rubykaigi01
怠惰なRubyistへの道 fukuoka rubykaigi01nagachika t
 
Node.jsでつくるNode.js ミニインタープリター&コンパイラー
Node.jsでつくるNode.js ミニインタープリター&コンパイラーNode.jsでつくるNode.js ミニインタープリター&コンパイラー
Node.jsでつくるNode.js ミニインタープリター&コンパイラーmganeko
 
"Puzzle-Based Automatic Testing: Bringing Humans into the Loop by Solving Puz...
"Puzzle-Based Automatic Testing: Bringing Humans into the Loop by Solving Puz..."Puzzle-Based Automatic Testing: Bringing Humans into the Loop by Solving Puz...
"Puzzle-Based Automatic Testing: Bringing Humans into the Loop by Solving Puz...nkazuki
 
怠惰なRubyistへの道
怠惰なRubyistへの道怠惰なRubyistへの道
怠惰なRubyistへの道nagachika t
 
Kink: invokedynamic on a prototype-based language
Kink: invokedynamic on a prototype-based languageKink: invokedynamic on a prototype-based language
Kink: invokedynamic on a prototype-based languageTaku Miyakawa
 
24時間でiOSアプリ-Twitterクライアント-の作成にチャレンジ ver1.1
24時間でiOSアプリ-Twitterクライアント-の作成にチャレンジ ver1.124時間でiOSアプリ-Twitterクライアント-の作成にチャレンジ ver1.1
24時間でiOSアプリ-Twitterクライアント-の作成にチャレンジ ver1.1聡 中川
 
Lispmeetup #53 PythonベースのLisp方言、 Hyのすすめ
Lispmeetup #53 PythonベースのLisp方言、 HyのすすめLispmeetup #53 PythonベースのLisp方言、 Hyのすすめ
Lispmeetup #53 PythonベースのLisp方言、 HyのすすめSatoshi imai
 
並行プログラミングと継続モナド
並行プログラミングと継続モナド並行プログラミングと継続モナド
並行プログラミングと継続モナドKousuke Ruichi
 
Oocon2020 presentation slide @kozukorio
Oocon2020 presentation slide @kozukorioOocon2020 presentation slide @kozukorio
Oocon2020 presentation slide @kozukorioHirokazu Kobayashi
 
HiroshimaJUG の 「Java8 Lambda ハンズオン with すごい広島」 を5分で振り返る
HiroshimaJUG の「Java8 Lambda ハンズオン with すごい広島」を5分で振り返るHiroshimaJUG の「Java8 Lambda ハンズオン with すごい広島」を5分で振り返る
HiroshimaJUG の 「Java8 Lambda ハンズオン with すごい広島」 を5分で振り返るtsudaa
 

Similaire à Haskell超初心者勉強会14 (20)

Or seminar2011final
Or seminar2011finalOr seminar2011final
Or seminar2011final
 
How wonderful to be (statically) typed 〜型が付くってスバラシイ〜
How wonderful to be (statically) typed 〜型が付くってスバラシイ〜How wonderful to be (statically) typed 〜型が付くってスバラシイ〜
How wonderful to be (statically) typed 〜型が付くってスバラシイ〜
 
Scalaプログラミング・マニアックス
Scalaプログラミング・マニアックスScalaプログラミング・マニアックス
Scalaプログラミング・マニアックス
 
mxnetで頑張る深層学習
mxnetで頑張る深層学習mxnetで頑張る深層学習
mxnetで頑張る深層学習
 
Javaはどのように動くのか~スライドでわかるJVMの仕組み
Javaはどのように動くのか~スライドでわかるJVMの仕組みJavaはどのように動くのか~スライドでわかるJVMの仕組み
Javaはどのように動くのか~スライドでわかるJVMの仕組み
 
Real World OCamlを読んでLispと協調してみた
Real World OCamlを読んでLispと協調してみたReal World OCamlを読んでLispと協調してみた
Real World OCamlを読んでLispと協調してみた
 
Java オブジェクトの内部構造
Java オブジェクトの内部構造Java オブジェクトの内部構造
Java オブジェクトの内部構造
 
Gurobi python
Gurobi pythonGurobi python
Gurobi python
 
怠惰なRubyistへの道 fukuoka rubykaigi01
怠惰なRubyistへの道 fukuoka rubykaigi01怠惰なRubyistへの道 fukuoka rubykaigi01
怠惰なRubyistへの道 fukuoka rubykaigi01
 
Node.jsでつくるNode.js ミニインタープリター&コンパイラー
Node.jsでつくるNode.js ミニインタープリター&コンパイラーNode.jsでつくるNode.js ミニインタープリター&コンパイラー
Node.jsでつくるNode.js ミニインタープリター&コンパイラー
 
"Puzzle-Based Automatic Testing: Bringing Humans into the Loop by Solving Puz...
"Puzzle-Based Automatic Testing: Bringing Humans into the Loop by Solving Puz..."Puzzle-Based Automatic Testing: Bringing Humans into the Loop by Solving Puz...
"Puzzle-Based Automatic Testing: Bringing Humans into the Loop by Solving Puz...
 
怠惰なRubyistへの道
怠惰なRubyistへの道怠惰なRubyistへの道
怠惰なRubyistへの道
 
Scrum alliance regional gathering tokyo 2013 pub
Scrum alliance regional gathering tokyo 2013 pubScrum alliance regional gathering tokyo 2013 pub
Scrum alliance regional gathering tokyo 2013 pub
 
Kink: invokedynamic on a prototype-based language
Kink: invokedynamic on a prototype-based languageKink: invokedynamic on a prototype-based language
Kink: invokedynamic on a prototype-based language
 
24時間でiOSアプリ-Twitterクライアント-の作成にチャレンジ ver1.1
24時間でiOSアプリ-Twitterクライアント-の作成にチャレンジ ver1.124時間でiOSアプリ-Twitterクライアント-の作成にチャレンジ ver1.1
24時間でiOSアプリ-Twitterクライアント-の作成にチャレンジ ver1.1
 
Lispmeetup #53 PythonベースのLisp方言、 Hyのすすめ
Lispmeetup #53 PythonベースのLisp方言、 HyのすすめLispmeetup #53 PythonベースのLisp方言、 Hyのすすめ
Lispmeetup #53 PythonベースのLisp方言、 Hyのすすめ
 
並行プログラミングと継続モナド
並行プログラミングと継続モナド並行プログラミングと継続モナド
並行プログラミングと継続モナド
 
Oocon2020 presentation slide @kozukorio
Oocon2020 presentation slide @kozukorioOocon2020 presentation slide @kozukorio
Oocon2020 presentation slide @kozukorio
 
たのしい関数型
たのしい関数型たのしい関数型
たのしい関数型
 
HiroshimaJUG の 「Java8 Lambda ハンズオン with すごい広島」 を5分で振り返る
HiroshimaJUG の「Java8 Lambda ハンズオン with すごい広島」を5分で振り返るHiroshimaJUG の「Java8 Lambda ハンズオン with すごい広島」を5分で振り返る
HiroshimaJUG の 「Java8 Lambda ハンズオン with すごい広島」 を5分で振り返る
 

Plus de Takashi Kawachi

Plus de Takashi Kawachi (6)

例外のlogを快適に
例外のlogを快適に例外のlogを快適に
例外のlogを快適に
 
MacroPyがすごい
MacroPyがすごいMacroPyがすごい
MacroPyがすごい
 
Silhouette intro
Silhouette introSilhouette intro
Silhouette intro
 
最小 Hello World! チャレンジ
最小 Hello World! チャレンジ最小 Hello World! チャレンジ
最小 Hello World! チャレンジ
 
Sbt doctest
Sbt doctestSbt doctest
Sbt doctest
 
Sbt lock1
Sbt lock1Sbt lock1
Sbt lock1
 

Haskell超初心者勉強会14