SlideShare uma empresa Scribd logo
1 de 30
Baixar para ler offline
MP in Scala
MP = Monadic Programming
1. モナドとは何か
2. モナドの基本的な扱い方
3. モナド変換子の使い方
自己紹介
(defprofile
大橋 賢人 [OHASHI Kent]
:company 株式会社オプト テクノロジー開発2部
:github @lagenorhynque
:twitter @lagenorhynque
:languages [Python Haskell Clojure Scala English français Deutsch русский]
:interests [プログラミング 語学 数学])
モナド(Monad)とは
一言で言えば、 flatMapできる型クラス(type class)。
F[A] => (A => F[B]) => F[B]
型クラスFunctor, Applicativeの上位互換。
// scalaz.Monad
trait Monad[F[_]] extends Applicative[F] with Bind[F] {
abstract def bind[A, B](fa: F[A])(f: (A) ⇒ F[B]): F[B]
abstract def point[A](a: ⇒ A): F[A]
...
}
-- Haskell
class Applicative m => Monad m where
(>>=) :: forall a b. m a -> (a -> m b) -> m b
return :: a -> m a
...
モナドの具体例
例えば、 。Option
標準ライブラリでは型クラスとして実装されているわけではないが
Functor, Applicative, Monadに相当する機能を備えている。
Functorの map
F[A] => (A => B) => F[B]
にあたる。scalaz.Functor.map
val n: Option[Int] = Some(1)
val f: Int => String = x => x.toString
// Option#map
n.map(f)
// Option#flatMap による実装
n.flatMap { a =>
Some(f(a))
}
// for式による実装
for {
a <- n
} yield f(a)
Applicativeの ap / <*>
F[A] => F[A => B] => F[B]
, にあたる。scalaz.Apply.apscalaz.syntax.ApplyOps.<*>
val n: Option[Int] = Some(1)
val f: Option[Int => String] = Some(x => x.toString)
// Option#flatMap, Option#map による実装
n.flatMap { a =>
f.map { g =>
g(a)
}
}
// for式による実装
for {
a <- n
g <- f
} yield g(a)
Monadの flatMap / bind / >>=
F[A] => (A => F[B]) => F[B]
, にあたる。scalaz.Bind.bindscalaz.syntax.BindOps.>>=
val n: Option[Int] = Some(1)
val f: Int => Option[String] = x => Some(x.toString)
// Option#flatMap
n.flatMap(f)
// for式による実装
for {
a <- n
b <- f(a)
} yield b
同種のモナドを扱う場合
例えば、 Optionを単独で使う場合
同種のモナドを扱う場合
(1) パターンマッチ
構造に注目して分解(unapply, destructure)する。
case class User(firstName: Option[String], lastName: Option[String])
def userName(user: User): Option[String] = user match {
case User(Some(first), Some(last)) => Some(s"$first $last")
case _ => None
}
同種のモナドを扱う場合
(2) 高階関数
高階関数map, flatMap, etc.を組み合わせる。
case class User(firstName: Option[String], lastName: Option[String])
def userName(user: User): Option[String] =
user.firstName.flatMap { first =>
user.lastName.map { last =>
s"$first $last"
}
}
同種のモナドを扱う場合
(3) for式
モナドのためのシンタックスシュガーを活用する。
case class User(firstName: Option[String], lastName: Option[String])
def userName(user: User): Option[String] =
for {
first <- user.firstName
last <- user.lastName
} yield s"$first $last"
異種のモナドが混在する場合
例えば、 Optionと を組み合わせてscalaz./
E / Option[A]として扱う必要がある場合
異種のモナドが混在する場合
(1) パターンマッチ
import scalaz._, Scalaz._
case class User(id: Int,
firstName: Option[String],
lastName: Option[String])
def userRole(id: Int): Error / Role = ???
def userInfo(user: User): Error / Option[String] =
userRole(user.id) match {
case /-(role) => user match {
case User(_, Some(first), Some(last)) =>
/-(Some(s"$first $last: $role"))
case _ =>
/-(None)
}
case -/(error) => -/(error)
}
問題点
複数階層のモナドの分解・再構築が煩わしい
構造に強く依存しているため変更に弱い
パターンマッチがネストして書きづらく読みづらい
異種のモナドが混在する場合
(2) 高階関数
import scalaz._, Scalaz._
case class User(id: Int,
firstName: Option[String],
lastName: Option[String])
def userRole(id: Int): Error / Role = ???
def userInfo(user: User): Error / Option[String] =
userRole(user.id).map { role =>
user.firstName.flatMap { first =>
user.lastName.map { last =>
s"$first $last: $role"
}
}
}
問題点
構造を直接扱う必要はないが関数がネストして書きづらく読みづらい
異種のモナドが混在する場合
(3) for式
import scalaz._, Scalaz._
case class User(id: Int,
firstName: Option[String],
lastName: Option[String])
def userRole(id: Int): Error / Role = ???
def userInfo(user: User): Error / Option[String] =
for {
role <- userRole(user.id)
} yield for {
first <- user.firstName
last <- user.lastName
} yield s"$first $last: $role"
問題点
関数はネストしないがfor式が連鎖して書きづらく読みづらい
モナド変換子(monad transformer)とは
一言で言えば、あるモナドに別のモナドを上乗せ(合成)したモナド。
ネストしたモナドをネストしていないかのように扱えるようになる。
e.g. , ,scalaz.OptionTscalaz.EitherTscalaz.ListT
モナド変換子の生成と変換
// 型パラメータを1個とる型F(モナド)
type F[A] = ???
// FとOptionでネストしたモナド
val fOptionA: F[Option[A]] = ???
// OptionとFを合成したOptionT
val optionTFA: OptionT[F, A] = ???
// Option
val optionA: Option[A] = ???
// F
val fA: F[A] = ???
// F[Option[A]] → OptionT[F, A]
OptionT.optionT(fOptionA)
// OptionT[F, A] → F[Option[A]]
optionTFA.run
// Option[A] → F[Option[A]] → OptionT[F, A]
OptionT.optionT(optionA.point[F])
// F[A] → OptionT[F, A]
fA.liftM[OptionT]
モナド変換子の導入
ここではモナド変換子scalaz.OptionTを利用して
Optionとscalaz./を合成してみる。
import scalaz._, Scalaz._
case class User(id: Int,
firstName: Option[String],
lastName: Option[String])
def userRole(id: Int): Error / Role = ???
type ErrorOrResult[+A] = Error / A
def userInfo(user: User): Error / Option[String] =
(for {
role <- userRole(user.id).liftM[OptionT]
first <- OptionT.optionT(user.firstName.point[ErrorOrResult])
last <- OptionT.optionT(user.lastName.point[ErrorOrResult])
} yield s"$first $last: $role").run
Option[+A]とE / Aをfor式1つでシンプルに扱える
モナド変換子への変換がやや冗長
さらにリファクタ
モナド変換子への変換を関数として抽出してみる。
import scalaz._, Scalaz._
case class User(id: Int,
firstName: Option[String],
lastName: Option[String])
def userRole(id: Int): Error / Role = ???
type ErrorOrResult[+A] = Error / A
def fromOption[A](a: Option[A]): OptionT[ErrorOrResult, A] =
OptionT.optionT(a.point[ErrorOrResult])
def fromEither[A](a: ErrorOrResult[A]): OptionT[ErrorOrResult, A] =
a.liftM[OptionT]
def userInfo(user: User): Error / Option[String] =
(for {
role <- userRole(user.id) ▹ fromEither
first <- user.firstName ▹ fromOption
last <- user.lastName ▹ fromOption
} yield s"$first $last: $role").run
ちなみに
Q: このtype aliasは何のためにあるのか?
type ErrorOrResult[+A] = Error / A
A: モナド変換子の型パラメータにカインド(kind)を合わせるため。
型 カインド
OptionT[F[_], A]のF[_] * -> *
/[+A, +B] * -> * -> *
// 方法1: type aliasする
type ErrorOrResult[+A] = Error / A
OptionT[ErrorOrResult, A]
// 方法2: インラインでtype aliasする(type lambda)
OptionT[({type λ[+α] = Error / α})#λ, A]
// 方法3: コンパイラプラグインKind Projectorを利用する
OptionT[Error / +?, A]
Further Reading
Functor, Applicative, Monadのシンプルな定式化- Qiita
ScalaでFutureとEitherを組み合わせたときに綺麗に書く方法- scala
とか・・・
Scalaz Monad Transformers - Underscore
独習Scalaz — モナド変換子
Easy Monad
Haskell モナド変換子超入門- Qiita
All About Monads - Sampou.Org
Source Code
Gist - lagenorhynque - monad-transformers

Mais conteúdo relacionado

Mais procurados

C++コミュニティーの中心でC++をDISる
C++コミュニティーの中心でC++をDISるC++コミュニティーの中心でC++をDISる
C++コミュニティーの中心でC++をDISるHideyuki Tanaka
 
Van laarhoven lens
Van laarhoven lensVan laarhoven lens
Van laarhoven lensNaoki Aoyama
 
20141128 iOSチーム勉強会 My Sweet Swift
20141128 iOSチーム勉強会 My Sweet Swift20141128 iOSチーム勉強会 My Sweet Swift
20141128 iOSチーム勉強会 My Sweet Swiftnecocen
 
Real World OCamlを読んでLispと協調してみた
Real World OCamlを読んでLispと協調してみたReal World OCamlを読んでLispと協調してみた
Real World OCamlを読んでLispと協調してみたblackenedgold
 
Implicit Explicit Scala
Implicit Explicit ScalaImplicit Explicit Scala
Implicit Explicit ScalaKota Mizushima
 
Freer Monads, More Extensible Effects
Freer Monads, More Extensible EffectsFreer Monads, More Extensible Effects
Freer Monads, More Extensible EffectsHiromi Ishii
 
Implicit Implicit Scala
Implicit Implicit ScalaImplicit Implicit Scala
Implicit Implicit ScalaKota Mizushima
 
ナウなヤングにバカうけのイカしたタグ付き共用体
ナウなヤングにバカうけのイカしたタグ付き共用体ナウなヤングにバカうけのイカしたタグ付き共用体
ナウなヤングにバカうけのイカしたタグ付き共用体digitalghost
 
(define)なしで再帰関数を定義する
(define)なしで再帰関数を定義する(define)なしで再帰関数を定義する
(define)なしで再帰関数を定義するblackenedgold
 
Swift らしい表現を目指そう #eventdots
Swift らしい表現を目指そう #eventdotsSwift らしい表現を目指そう #eventdots
Swift らしい表現を目指そう #eventdotsTomohiro Kumagai
 
Material
MaterialMaterial
Material_TUNE_
 
並行プログラミングと継続モナド
並行プログラミングと継続モナド並行プログラミングと継続モナド
並行プログラミングと継続モナドKousuke Ruichi
 
Swift 3 で新しくなったところ - 表面から見えにくいところを中心に紹介 #ISAOcorp
Swift 3 で新しくなったところ - 表面から見えにくいところを中心に紹介 #ISAOcorpSwift 3 で新しくなったところ - 表面から見えにくいところを中心に紹介 #ISAOcorp
Swift 3 で新しくなったところ - 表面から見えにくいところを中心に紹介 #ISAOcorpTomohiro Kumagai
 
Extensible Eff Applicative
Extensible Eff ApplicativeExtensible Eff Applicative
Extensible Eff ApplicativeSanshiro Yoshida
 
こわくない型クラス
こわくない型クラスこわくない型クラス
こわくない型クラスKota Mizushima
 

Mais procurados (20)

C++コミュニティーの中心でC++をDISる
C++コミュニティーの中心でC++をDISるC++コミュニティーの中心でC++をDISる
C++コミュニティーの中心でC++をDISる
 
Van laarhoven lens
Van laarhoven lensVan laarhoven lens
Van laarhoven lens
 
20141128 iOSチーム勉強会 My Sweet Swift
20141128 iOSチーム勉強会 My Sweet Swift20141128 iOSチーム勉強会 My Sweet Swift
20141128 iOSチーム勉強会 My Sweet Swift
 
Real World OCamlを読んでLispと協調してみた
Real World OCamlを読んでLispと協調してみたReal World OCamlを読んでLispと協調してみた
Real World OCamlを読んでLispと協調してみた
 
Implicit Explicit Scala
Implicit Explicit ScalaImplicit Explicit Scala
Implicit Explicit Scala
 
Haskell Lecture 2
Haskell Lecture 2Haskell Lecture 2
Haskell Lecture 2
 
Freer Monads, More Extensible Effects
Freer Monads, More Extensible EffectsFreer Monads, More Extensible Effects
Freer Monads, More Extensible Effects
 
Implicit Implicit Scala
Implicit Implicit ScalaImplicit Implicit Scala
Implicit Implicit Scala
 
Pythonintro
PythonintroPythonintro
Pythonintro
 
ナウなヤングにバカうけのイカしたタグ付き共用体
ナウなヤングにバカうけのイカしたタグ付き共用体ナウなヤングにバカうけのイカしたタグ付き共用体
ナウなヤングにバカうけのイカしたタグ付き共用体
 
(define)なしで再帰関数を定義する
(define)なしで再帰関数を定義する(define)なしで再帰関数を定義する
(define)なしで再帰関数を定義する
 
たのしい関数型
たのしい関数型たのしい関数型
たのしい関数型
 
Swift らしい表現を目指そう #eventdots
Swift らしい表現を目指そう #eventdotsSwift らしい表現を目指そう #eventdots
Swift らしい表現を目指そう #eventdots
 
Material
MaterialMaterial
Material
 
並行プログラミングと継続モナド
並行プログラミングと継続モナド並行プログラミングと継続モナド
並行プログラミングと継続モナド
 
Swift 3 で新しくなったところ - 表面から見えにくいところを中心に紹介 #ISAOcorp
Swift 3 で新しくなったところ - 表面から見えにくいところを中心に紹介 #ISAOcorpSwift 3 で新しくなったところ - 表面から見えにくいところを中心に紹介 #ISAOcorp
Swift 3 で新しくなったところ - 表面から見えにくいところを中心に紹介 #ISAOcorp
 
Extensible Eff Applicative
Extensible Eff ApplicativeExtensible Eff Applicative
Extensible Eff Applicative
 
 
  
 
 
こわくない型クラス
こわくない型クラスこわくない型クラス
こわくない型クラス
 
Find(1)
Find(1)Find(1)
Find(1)
 

Destaque

Clojure座談会 #1 LT 独自コレクションを定義しよう
Clojure座談会 #1 LT 独自コレクションを定義しようClojure座談会 #1 LT 独自コレクションを定義しよう
Clojure座談会 #1 LT 独自コレクションを定義しようKeisuke Fukuda
 
From Java To Clojure (English version)
From Java To Clojure (English version)From Java To Clojure (English version)
From Java To Clojure (English version)Kent Ohashi
 
おいしいLisp
おいしいLispおいしいLisp
おいしいLispKent Ohashi
 
From Java To Clojure
From Java To ClojureFrom Java To Clojure
From Java To ClojureKent Ohashi
 
Practical Phonetics (実践音声学)
Practical Phonetics (実践音声学)Practical Phonetics (実践音声学)
Practical Phonetics (実践音声学)Kent Ohashi
 

Destaque (6)

Clojure座談会 #1 LT 独自コレクションを定義しよう
Clojure座談会 #1 LT 独自コレクションを定義しようClojure座談会 #1 LT 独自コレクションを定義しよう
Clojure座談会 #1 LT 独自コレクションを定義しよう
 
Functional Way
Functional WayFunctional Way
Functional Way
 
From Java To Clojure (English version)
From Java To Clojure (English version)From Java To Clojure (English version)
From Java To Clojure (English version)
 
おいしいLisp
おいしいLispおいしいLisp
おいしいLisp
 
From Java To Clojure
From Java To ClojureFrom Java To Clojure
From Java To Clojure
 
Practical Phonetics (実践音声学)
Practical Phonetics (実践音声学)Practical Phonetics (実践音声学)
Practical Phonetics (実践音声学)
 

Semelhante a MP in Scala

今から始める Lens/Prism
今から始める Lens/Prism今から始める Lens/Prism
今から始める Lens/PrismNaoki Aoyama
 
モナドハンズオン前座
モナドハンズオン前座モナドハンズオン前座
モナドハンズオン前座bleis tift
 
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
 
Ekmett勉強会発表資料
Ekmett勉強会発表資料Ekmett勉強会発表資料
Ekmett勉強会発表資料時響 逢坂
 
What Dotty fixes @ Scala関西サミット
What Dotty fixes @ Scala関西サミットWhat Dotty fixes @ Scala関西サミット
What Dotty fixes @ Scala関西サミットTaisuke Oe
 
Essential Scala 第5章 シーケンス処理
Essential Scala 第5章 シーケンス処理Essential Scala 第5章 シーケンス処理
Essential Scala 第5章 シーケンス処理Takuya Tsuchida
 
【C++BUILDER STARTER チュートリアルシリーズ】シーズン2 C++Builderの部 第4回 ‟関数„
【C++BUILDER STARTER チュートリアルシリーズ】シーズン2 C++Builderの部 第4回 ‟関数„【C++BUILDER STARTER チュートリアルシリーズ】シーズン2 C++Builderの部 第4回 ‟関数„
【C++BUILDER STARTER チュートリアルシリーズ】シーズン2 C++Builderの部 第4回 ‟関数„和弘 井之上
 
Ekmett勉強会発表資料
Ekmett勉強会発表資料Ekmett勉強会発表資料
Ekmett勉強会発表資料時響 逢坂
 
2014年の社内新人教育テキスト #2(関数型言語からオブジェクト指向言語へ)
2014年の社内新人教育テキスト #2(関数型言語からオブジェクト指向言語へ)2014年の社内新人教育テキスト #2(関数型言語からオブジェクト指向言語へ)
2014年の社内新人教育テキスト #2(関数型言語からオブジェクト指向言語へ)Shin-ya Koga
 
すごいH 第12章モノイド
すごいH 第12章モノイドすごいH 第12章モノイド
すごいH 第12章モノイドShinta Hatatani
 
Scala の関数型プログラミングを支える技術
Scala の関数型プログラミングを支える技術Scala の関数型プログラミングを支える技術
Scala の関数型プログラミングを支える技術Naoki Aoyama
 
プログラミング言語Scala
プログラミング言語Scalaプログラミング言語Scala
プログラミング言語ScalaTanUkkii
 
Scalaによる型安全なエラーハンドリング
Scalaによる型安全なエラーハンドリングScalaによる型安全なエラーハンドリング
Scalaによる型安全なエラーハンドリングTanUkkii
 
リストモナドを作ってみた
リストモナドを作ってみたリストモナドを作ってみた
リストモナドを作ってみたAtsushi Kanehara
 
すごいHaskell 第7章 型や型クラスを自分で作ろう(後編)
すごいHaskell 第7章 型や型クラスを自分で作ろう(後編)すごいHaskell 第7章 型や型クラスを自分で作ろう(後編)
すごいHaskell 第7章 型や型クラスを自分で作ろう(後編)Nozomu Kaneko
 

Semelhante a MP in Scala (20)

今から始める Lens/Prism
今から始める Lens/Prism今から始める Lens/Prism
今から始める Lens/Prism
 
モナドハンズオン前座
モナドハンズオン前座モナドハンズオン前座
モナドハンズオン前座
 
Task
TaskTask
Task
 
How wonderful to be (statically) typed 〜型が付くってスバラシイ〜
How wonderful to be (statically) typed 〜型が付くってスバラシイ〜How wonderful to be (statically) typed 〜型が付くってスバラシイ〜
How wonderful to be (statically) typed 〜型が付くってスバラシイ〜
 
Ekmett勉強会発表資料
Ekmett勉強会発表資料Ekmett勉強会発表資料
Ekmett勉強会発表資料
 
Swiftおさらい
SwiftおさらいSwiftおさらい
Swiftおさらい
 
What Dotty fixes @ Scala関西サミット
What Dotty fixes @ Scala関西サミットWhat Dotty fixes @ Scala関西サミット
What Dotty fixes @ Scala関西サミット
 
Essential Scala 第5章 シーケンス処理
Essential Scala 第5章 シーケンス処理Essential Scala 第5章 シーケンス処理
Essential Scala 第5章 シーケンス処理
 
【C++BUILDER STARTER チュートリアルシリーズ】シーズン2 C++Builderの部 第4回 ‟関数„
【C++BUILDER STARTER チュートリアルシリーズ】シーズン2 C++Builderの部 第4回 ‟関数„【C++BUILDER STARTER チュートリアルシリーズ】シーズン2 C++Builderの部 第4回 ‟関数„
【C++BUILDER STARTER チュートリアルシリーズ】シーズン2 C++Builderの部 第4回 ‟関数„
 
Applicative functor
Applicative functorApplicative functor
Applicative functor
 
Ekmett勉強会発表資料
Ekmett勉強会発表資料Ekmett勉強会発表資料
Ekmett勉強会発表資料
 
2014年の社内新人教育テキスト #2(関数型言語からオブジェクト指向言語へ)
2014年の社内新人教育テキスト #2(関数型言語からオブジェクト指向言語へ)2014年の社内新人教育テキスト #2(関数型言語からオブジェクト指向言語へ)
2014年の社内新人教育テキスト #2(関数型言語からオブジェクト指向言語へ)
 
すごいH 第12章モノイド
すごいH 第12章モノイドすごいH 第12章モノイド
すごいH 第12章モノイド
 
Scala の関数型プログラミングを支える技術
Scala の関数型プログラミングを支える技術Scala の関数型プログラミングを支える技術
Scala の関数型プログラミングを支える技術
 
Actor&stm
Actor&stmActor&stm
Actor&stm
 
20180728 halide-study
20180728 halide-study20180728 halide-study
20180728 halide-study
 
プログラミング言語Scala
プログラミング言語Scalaプログラミング言語Scala
プログラミング言語Scala
 
Scalaによる型安全なエラーハンドリング
Scalaによる型安全なエラーハンドリングScalaによる型安全なエラーハンドリング
Scalaによる型安全なエラーハンドリング
 
リストモナドを作ってみた
リストモナドを作ってみたリストモナドを作ってみた
リストモナドを作ってみた
 
すごいHaskell 第7章 型や型クラスを自分で作ろう(後編)
すごいHaskell 第7章 型や型クラスを自分で作ろう(後編)すごいHaskell 第7章 型や型クラスを自分で作ろう(後編)
すごいHaskell 第7章 型や型クラスを自分で作ろう(後編)
 

Mais de Kent Ohashi

インターフェース定義言語から学ぶモダンなWeb API方式: REST, GraphQL, gRPC
インターフェース定義言語から学ぶモダンなWeb API方式: REST, GraphQL, gRPCインターフェース定義言語から学ぶモダンなWeb API方式: REST, GraphQL, gRPC
インターフェース定義言語から学ぶモダンなWeb API方式: REST, GraphQL, gRPCKent Ohashi
 
Team Geek Revisited
Team Geek RevisitedTeam Geek Revisited
Team Geek RevisitedKent Ohashi
 
Scala vs Clojure?: The Rise and Fall of Functional Languages in Opt Technologies
Scala vs Clojure?: The Rise and Fall of Functional Languages in Opt TechnologiesScala vs Clojure?: The Rise and Fall of Functional Languages in Opt Technologies
Scala vs Clojure?: The Rise and Fall of Functional Languages in Opt TechnologiesKent Ohashi
 
Clojureコレクションで探るimmutableでpersistentな世界
Clojureコレクションで探るimmutableでpersistentな世界Clojureコレクションで探るimmutableでpersistentな世界
Clojureコレクションで探るimmutableでpersistentな世界Kent Ohashi
 
英語学習者のためのフランス語文法入門: フランス語完全理解(?)
英語学習者のためのフランス語文法入門: フランス語完全理解(?)英語学習者のためのフランス語文法入門: フランス語完全理解(?)
英語学習者のためのフランス語文法入門: フランス語完全理解(?)Kent Ohashi
 
JavaからScala、そしてClojureへ: 実務で活きる関数型プログラミング
JavaからScala、そしてClojureへ: 実務で活きる関数型プログラミングJavaからScala、そしてClojureへ: 実務で活きる関数型プログラミング
JavaからScala、そしてClojureへ: 実務で活きる関数型プログラミングKent Ohashi
 
実用のための語源学入門
実用のための語源学入門実用のための語源学入門
実用のための語源学入門Kent Ohashi
 
メタプログラミング入門
メタプログラミング入門メタプログラミング入門
メタプログラミング入門Kent Ohashi
 
労働法の世界
労働法の世界労働法の世界
労働法の世界Kent Ohashi
 
Clojureで作る"simple"なDSL
Clojureで作る"simple"なDSLClojureで作る"simple"なDSL
Clojureで作る"simple"なDSLKent Ohashi
 
RDBでのツリー表現入門
RDBでのツリー表現入門RDBでのツリー表現入門
RDBでのツリー表現入門Kent Ohashi
 
Everyday Life with clojure.spec
Everyday Life with clojure.specEveryday Life with clojure.spec
Everyday Life with clojure.specKent Ohashi
 
たのしい多言語学習
たのしい多言語学習たのしい多言語学習
たのしい多言語学習Kent Ohashi
 
Ductモジュール入門
Ductモジュール入門Ductモジュール入門
Ductモジュール入門Kent Ohashi
 
Clojure REPL: The Good Parts
Clojure REPL: The Good PartsClojure REPL: The Good Parts
Clojure REPL: The Good PartsKent Ohashi
 
"Simple Made Easy" Made Easy
"Simple Made Easy" Made Easy"Simple Made Easy" Made Easy
"Simple Made Easy" Made EasyKent Ohashi
 
Clojurian Conquest
Clojurian ConquestClojurian Conquest
Clojurian ConquestKent Ohashi
 
ClojurianからみたElixir
ClojurianからみたElixirClojurianからみたElixir
ClojurianからみたElixirKent Ohashi
 
GraphQL API in Clojure
GraphQL API in ClojureGraphQL API in Clojure
GraphQL API in ClojureKent Ohashi
 

Mais de Kent Ohashi (20)

インターフェース定義言語から学ぶモダンなWeb API方式: REST, GraphQL, gRPC
インターフェース定義言語から学ぶモダンなWeb API方式: REST, GraphQL, gRPCインターフェース定義言語から学ぶモダンなWeb API方式: REST, GraphQL, gRPC
インターフェース定義言語から学ぶモダンなWeb API方式: REST, GraphQL, gRPC
 
Team Geek Revisited
Team Geek RevisitedTeam Geek Revisited
Team Geek Revisited
 
Scala vs Clojure?: The Rise and Fall of Functional Languages in Opt Technologies
Scala vs Clojure?: The Rise and Fall of Functional Languages in Opt TechnologiesScala vs Clojure?: The Rise and Fall of Functional Languages in Opt Technologies
Scala vs Clojure?: The Rise and Fall of Functional Languages in Opt Technologies
 
Clojureコレクションで探るimmutableでpersistentな世界
Clojureコレクションで探るimmutableでpersistentな世界Clojureコレクションで探るimmutableでpersistentな世界
Clojureコレクションで探るimmutableでpersistentな世界
 
英語学習者のためのフランス語文法入門: フランス語完全理解(?)
英語学習者のためのフランス語文法入門: フランス語完全理解(?)英語学習者のためのフランス語文法入門: フランス語完全理解(?)
英語学習者のためのフランス語文法入門: フランス語完全理解(?)
 
JavaからScala、そしてClojureへ: 実務で活きる関数型プログラミング
JavaからScala、そしてClojureへ: 実務で活きる関数型プログラミングJavaからScala、そしてClojureへ: 実務で活きる関数型プログラミング
JavaからScala、そしてClojureへ: 実務で活きる関数型プログラミング
 
実用のための語源学入門
実用のための語源学入門実用のための語源学入門
実用のための語源学入門
 
メタプログラミング入門
メタプログラミング入門メタプログラミング入門
メタプログラミング入門
 
労働法の世界
労働法の世界労働法の世界
労働法の世界
 
Clojureで作る"simple"なDSL
Clojureで作る"simple"なDSLClojureで作る"simple"なDSL
Clojureで作る"simple"なDSL
 
RDBでのツリー表現入門
RDBでのツリー表現入門RDBでのツリー表現入門
RDBでのツリー表現入門
 
GraphQL入門
GraphQL入門GraphQL入門
GraphQL入門
 
Everyday Life with clojure.spec
Everyday Life with clojure.specEveryday Life with clojure.spec
Everyday Life with clojure.spec
 
たのしい多言語学習
たのしい多言語学習たのしい多言語学習
たのしい多言語学習
 
Ductモジュール入門
Ductモジュール入門Ductモジュール入門
Ductモジュール入門
 
Clojure REPL: The Good Parts
Clojure REPL: The Good PartsClojure REPL: The Good Parts
Clojure REPL: The Good Parts
 
"Simple Made Easy" Made Easy
"Simple Made Easy" Made Easy"Simple Made Easy" Made Easy
"Simple Made Easy" Made Easy
 
Clojurian Conquest
Clojurian ConquestClojurian Conquest
Clojurian Conquest
 
ClojurianからみたElixir
ClojurianからみたElixirClojurianからみたElixir
ClojurianからみたElixir
 
GraphQL API in Clojure
GraphQL API in ClojureGraphQL API in Clojure
GraphQL API in Clojure
 

MP in Scala