SlideShare a Scribd company logo
1 of 175
Download to read offline
───When You Will Try Haskell
これから Haskell を書くにあたって
目次
3頁 … はじめに
9頁 … GHC 7.8 からの変更点
69頁 … Haskell が遅いと言われるワケとか
106頁 … 知らないと損する言語拡張たち
150頁 … FFI の話
161頁 … おまけ
はじめに
Who Am I?
twitter: func(@func_hs)
Haskell使いだったり、Clojure使いだったり。
現在求職中
最近E本ゲットしたからErlangも勉強する(その内)
はじめに
本発表の目的
Haskell には意外と落とし穴がある。
はじめに
本発表の目的
Haskell には意外と落とし穴がある。
✔ 計算量(オーダ)
はじめに
本発表の目的
Haskell には意外と落とし穴がある。
✔ 計算量(オーダ)
✔ メモリ使用量
はじめに
本発表の目的
Haskell には意外と落とし穴がある。
✔ 計算量(オーダ)
✔ メモリ使用量
✔ 言語仕様や処理系の実装のあれこれ
はじめに
本発表の目的
Haskell には意外と落とし穴がある。
✔ 計算量(オーダ)
✔ メモリ使用量
✔ 言語仕様や処理系の実装のあれこれ
これらへの注意の仕方と対処法を知る
GHC 7.8 からの変更点
10頁 … Monad Proposal
22頁 … Foldable
43頁 … Traversable
57頁 … Prelude の関数の変化
63頁 … 変更後の標準の型クラス全体図
67頁 … OpenGL から見る実装例
Monad Proposal
正確には Functor-Applicative-Monad Proposal
Monad のリファクタリングの提案
Monad は正式に Applicative の子型クラスに
話題自体は2014年よりも前から始まっていた。
最初期の Haskell では繋がっていたらしい。しかし…
親型クラスのメソッドをデフォルトで実装する機能がなかった。
Monad Proposal
instance 宣言のおさらい
記法
* instance C1 T1 where ...
* instance C1 a => T1 a where ...
* instance C1 a => Cn (T1 a) where ...
型クラスの実装をデータ型に対して与える
Monad Proposal
型変数のないデータ型への実装
instance C1 T1 where
f x = ...
型クラスの型変数は書かない
Monad Proposal
型変数のあるデータ型への実装
instance C1 a => T1 a where
f x = ...
instance (C1 a, C2 a, ...) => T1 a where
f x = ...
インスタンスを与える型変数を明示する
Monad Proposal
特定のインスタンスを持つデータ型への実装
instance C1 a => Cn (T1 a) where
f x = ...
instance (C1 a, C2 a,...) => Cn (T1 a) where
f x = ...
特定する型クラスも明示する
Monad Proposal
自動で実装できる型クラス
➜ deriving 句で導出できる型クラス
Eq, Ord, Enum, Bounded, Read, Show
コンストラクタの並び等から自明に導ける。
(もちろん自前で書いてもよい)
Monad Proposal
自動で実装できる型クラス
✔ 自明で導くことができる
✔ その型自身が直接依存する型クラス
に限る
Monad Proposal
Monad と Applicative の実装は?
❌自明では導くことができない
これら 2 つはコンテナの中身をどう扱うかの話
❌Applicative は Monad の親クラス
Monad のインスタンスを持つ型が直接依存しているわけではない。
Monad Proposal
公式の対応
return = pure
Monad の return の実装を Applicative の pure にリファクタリング
<*> = ap
コンテナから値を取り出し関数を適用するという点で同義
Monad Proposal
公式の対応
* pure :: a -> f a
* return :: a -> m a
* <*> :: f (a -> b) -> f a -> f b
* ap :: m (a -> b) -> m a -> m b
コンテキストが変わるだけ
Monad Proposal
公式の対応
Functor と Applicative の実装
➜ サードパーティが各自実装する形に
利便性より理論を優先?
Monad Proposal
Monad Proposal まとめ
✔ 2014年(GHC 7.8)以前に実装したモナドは
✔ リファクタリングしなきゃ(使命感)
Foldable
実装のイメージ
x1 x2 x3 x4 x5 …………………………… xN
f
?
コンテナの要素を一つに畳む
Foldable
期待される性質
✔ foldr f z t =
appEndo (foldMap (Endo . f) t) z
✔ foldl f z t =
appEndo (getDual (Dual . Endo . flip f) t)) z
✔ fold =
foldMap id
Foldable
期待される性質
Endo / appEndo
Dual / getDual
どちらも Data.Monoid モジュールにある
データ型
Foldable
期待される性質
newtype Endo a = Endo {appEndo :: a -> a}
モノイドのコンテキストで関数を合成する
Foldable
期待される性質
newtype Endo a = Endo {appEndo :: a -> a}
➜ instance Monoid (Endo a) where
mempty = Endo id
Endo f `mappend` Endo g = Endo (f . g)
Foldable
期待される性質
newtype Dual a = Dual {getDual :: a}
値を合成させるためのコンテナ
Foldable
期待される性質
newtype Dual a = Dual {getDual :: a}
➜ instance Monoid a => Monoid (Dual a)
where
mempty = Dual mempty
Dual x `mappend` Dual y =
Dual (x `mappned` y)
Foldable
Monoid に期待される性質
✔ mappend mempty x = x
✔ mappend x mempty = x
✔ mappend x (mappend y z) =
mappend (mappend x y) z
✔ mconcat = foldr mappend mempty
Foldable
Monoid に期待される性質
mappend mempty x = x
mappend x mempty = x
左単位元と右単位元の保証
Foldable
Monoid に期待される性質
mappend x (mappend y z) =
mappend (mappend x y) z
結合則の保証
Foldable
Monoid に期待される性質
mconcat = foldr mappend mempty
連結した結果が正しく閉じていることの保証
Foldable
Monoid に期待される性質
この内、必ず実装が必要なのは…
✔ mempty
✔ mappend
の 2 つ
Foldable
Monoid に期待される性質
mconcat にはデフォルト実装がある
➜ 特に必要なければ改めて実装しなくてよい
Foldable
話を戻して Foldable の話
foldr f z t =
appEndo (foldMap (Endo . f) t) z
foldl f z t =
appEndo (getDual (Dual . Endo . flip f) t)) z
要素の畳み方を定義する必要がある
Foldable
話を戻して Foldable の話
✔ foldMap
✔ foldr
最低限実装が必要なのはこの 2 つの内
少なくとも 1 つ
Foldable
話を戻して Foldable の話
✔ foldMap
✔ foldr
双方にデフォルト実装がある
➜ 片方が決まればもう片方も自動的に決まる
Foldable
話を戻して Foldable の話
foldMap :: Monoid m => (a -> m) -> t a -> m
foldMap f = foldr (mappend . f) mempty
Foldable のインスタンスを持つコンテナの要素を
Monoid に型変換させる
Foldable
話を戻して Foldable の話
foldr :: (a -> b -> b) -> b -> t a -> b
foldr f z t = appEndo (foldMap (Endo #. f) t) z
コンテナの中身をモノイドのコンテキストに
乗せながら畳んでいく
Foldable
話を戻して Foldable の話
foldr :: (a -> b -> b) -> b -> t a -> b
foldr f z t = appEndo (foldMap (Endo #. f) t) z
(´・_・`).oO((#.) ってなんだ?)
Foldable
話を戻して Foldable の話
(#.) :: (b -> c) -> (a -> b) -> (a -> c)
(#.) _f = coerce
coerce :: Coercible * a b => a -> b
coerce = let x = x in x
安全かつ強制的に型変換させるための関数
Foldable
Foldable まとめ
✔ 要素が Monoid のインスタンスであれば
どんな値も畳むことができる
✔ Endo は関数合成用のコンテナ
Dual は値合成用のコンテナ
✔ Monoid 用のデータ型は他にもあるよ!
Traversable
実装のイメージ
コンテナの要素に関数を適用し、入れ直す
x1 x2 x3 x4 x5 xN……………………………
f
y1 y2 y3 y4 y5 yN……………………………
Traversable
最低限実装が必要なメソッド
✔ traverse
✔ sequenceA
この 2 つの内いずれか 1 つ
双方にデフォルト実装がある。以下省略
Traversable
最低限実装が必要なメソッド
traverse
:: Applicative f => (a -> f b) -> t a -> f (t b)
traverse f = sequenceA . fmap f
コンテナの要素を走査しながら関数を適用
していく
Traversable
最低限実装が必要なメソッド
traverse
:: Applicative f => (a -> f b) -> t a -> f (t b)
traverse f = sequenceA . fmap f
コンテナが入れ替わることに注意
Traversable
最低限実装が必要なメソッド
sequenceA :: Applicative f => t (f a) -> f (t a)
sequenceA = traverse id
走査するだけ
(中の値自体には変更を加えない)
Traversable
最低限実装が必要なメソッド
sequenceA :: Applicative f => t (f a) -> f (t a)
sequenceA = traverse id
コンテナが入れ替わることに注意
(大事なことなのでry)
Traversable
最低限実装が必要なメソッド
コンテナを入れ替える理由
✔ 無駄なネストを除去し、
✔ 型の表現を簡潔にするため
(型注釈も込みで)
実装次第でより深いネストも走査できる
Traversable
最低限実装が必要なメソッド
コンテナを入れ替える理由
✔ 無駄なネストを除去し、
✔ 型の表現を簡潔にするため
(型注釈も込みで)
ただし注意が必要
Traversable
期待される性質
✔ t . traverse f =
traverse (t . f)
✔ traverse Identity =
Identity
✔ traverse (Compose . fmap g . f) =
Compose . fmap (traverse g) . traverse f
Traversable
期待される性質
✔ t . sequenceA =
sequenceA . fmap t
✔ sequenceA . fmap Identity =
Identity
✔ sequenceA . fmap Compose =
Compose . fmap sequenceA . sequenceA
Traversable
期待される性質
✔ t . traverse f = traverse (t . f)
✔ t . sequenceA = sequenceA . fmap t
関数合成の自然性の保証
(関数合成の効率化)
Traversable
期待される性質
✔ traverse Identity = Identity
✔ sequenceA . fmap Identity = Identity
同一性の保証
(id がちゃんとそのままの値を返すこと)
Traversable
期待される性質
✔ traverse (Compose . fmap g . f) =
Compose . fmap (traverse g) . traverse f
✔ sequenceA . fmap Compose =
Compose . fmap sequenceA . sequenceA
結合則の保証
Traversable
Traversable まとめ
✔ コンテナの要素を走査し、更新する
✔ その際にコンテナの構造を均して簡潔化する
✔ 中の要素は Applicative の実装が必要
(更新してコンテナに再適用させるため)
Prelude の関数の変化
意外とリファクタリングされていた
コンテナを畳むか走査するかで二分された
Prelude の関数の変化
意外とリファクタリングされていた
Foldableに所属
null, length, elem, notElem, maximum,
minimum, sum, product, and, or, any, all,
concat, concatMap, mapM_(forM_), sequence_
Prelude の関数の変化
意外とリファクタリングされていた
Traversableに所属
mapM(forM), sequence
Prelude の関数の変化
意外とリファクタリングされていた
mapM(forM)
コンテナ(変換結果)を返す
mapM_(forM_)
コンテナを返さない(命令の実行だけ)
Prelude の関数の変化
意外とリファクタリングされていた
sequence
結果を返すモナドなコンテナを評価する
sequence_
結果を返さないモナドなコンテナを評価する
Prelude の関数の変化
意外とリファクタリングされていた
sequence
評価して実行した結果をコンテナに詰め直す
sequence_
評価して実行するだけ(Unit型 `()` を返す)
変更後の標準の型クラス全体図
正式に養子縁組されました。
実線矢印が直接の継承関係
変更後の標準の型クラス全体図
正式に養子縁組されました。
点線矢印が挙動が類似している型クラス
変更後の標準の型クラス全体図
正式に養子縁組されました。
太線矢印(ArrowApply)は中の要素が Monad
変更後の標準の型クラス全体図
正式に養子縁組されました。
引用: Typeclassopedia
OpenGL から見る実装例
Foldable と Traversable はどう実装されているか
instance Foldable TexCoord4
foldr f a (TexCoord4 x y z w) =
x `f` (y `f` (z `f` (w `f` a)))
foldl f a (TexCoord4 x y z w) =
((((a `f` x) `f` y) `f` z) `f` w)
テクスチャ座標の畳込み等(一部抜粋)
OpenGL から見る実装例
Foldable と Traversable はどう実装されているか
instance Traversable TexCoord4 where
traverse f (TexCoord4 x y z w) =
pure TexCoord4 <*> f x <*> f y <*> f z
<*> f w
座標変換等(一部抜粋)
Haskell が遅いと言われるワケとか
70頁 … 評価しないものは溜まる
79頁 … データコンストラクタの中身
81頁 … 文字列の計算量とメモリ使用量
85頁 … タプル
88頁 … 自作データ型の高速化
97頁 … 型クラスの仕組み
102頁 … 競技プログラミングでの Haskell
評価しないものは溜まる
評価予定の値もスタックに
関数呼び出し中の未評価な値もスタックに乗る
➜ 評価されるまでは
評価しないものは溜まる
評価予定の値もスタックに
よくある階乗の計算
fact 0 = 1
fact n = n * fact (n - 1)
この n は何の問題もないように見えるが…
評価しないものは溜まる
評価予定の値もスタックに
よくある階乗の計算
fact 0 = 1
fact n = n * fact n
実は未評価なまま次の計算に渡されている
(評価されるのはパターンマッチの瞬間である)
評価しないものは溜まる
評価予定の値もスタックに
よくある階乗の計算
fact 0 = 1
fact n = n * fact n
引数部に名前だけの場合、それはパターンマッチ
されないことに注意。
評価しないものは溜まる
評価予定の値もスタックに
呼び出し回数が少ない内は無事に動く
➜ スタックもそれほど溜まらない
評価しないものは溜まる
評価予定の値もスタックに
しかし呼び出す回数が増えるにつれて、スタックは
どんどん溜まっていき、いずれは溢れてしまう
➜ 渡された値も未評価のまま…
この現象をスペースリークという
評価しないものは溜まる
評価予定の値もスタックに
対処法
✔ 他の関数に渡す前に強制的に評価させる
➜ seq 関数(この節で説明)
➜ BangPatterns(148頁)
評価しないものは溜まる
その場で評価させる方法
seq 関数
渡された値をその場で評価する(評価するだけ)
seq :: a -> b -> b
seq = let x = x in x
評価しないものは溜まる
その場で評価させる方法
階乗の例に適用してみる
fact 0 = 1
fact n = n `seq` n * fact (n - 1)
これにより、 n は seq 関数に渡され、その場で評
価されるようになった
データコンストラクタの中身
値がそのまま入るわけではない
Maybe Intの場合
Nothing Just
I# Int#
or P
P: ポインタ
データコンストラクタの中身
値がそのまま入るわけではない
Maybe Intの場合
Nothing Just
I# Int#
or P
P: ポインタ
実際の Int 型の値
文字列の計算量とメモリ使用量
計算量多そう…
: P
"Hello"(UTF-8)
P P
C# Char#
'H'
P P
C# Char#
'e'
P
C# Char#
'l'
P P P
C# Char#
'l'
P : : : :
文字列の計算量とメモリ使用量
計算量多い(確信)
"Hello"(UTF-8)
: P P P
C# Char#
'H'
P P
C# Char#
'e'
P
C# Char#
'l'
P P P
C# Char#
'l'
P : : : :
⑲
⑱
⑰⑯
⑮⑩⑤
⑭
⑬
⑫⑪
⑨
⑧
⑦⑥
③
②① ㉒㉑ ㉓
④
⑳
1 文字だけでも 4 回以上の計算が…
文字列の計算量とメモリ使用量
メモリ食いすぎィ!
構築子: 1 word
型引数: 1 word / arg
文字列 1 文字分 = 5 words
構築子(:) + ポインタ * 2 + Char のサイズ
1 word 2 words 2 words
C# + Char#
※32bit: 20 bytes, 64bit: 40 bytes
文字列の計算量とメモリ使用量
文字列効率化の試み
ライブラリレベル
➜ bytestring
➜ text
処理系レベル
➜ OverloadedStrings(98頁)
タプル
タプルも例外ではない
(,)
(Int, Int)
P P
I# Int# I# Int#
(Int, Int, Int)
(,) P P
I# Int#
P
I# Int#
I# Int#
タプル
タプルも例外ではない
(Maybe Int, Maybe Int)
(,) P P
Nothing or Just P
Nothing or Just P
I# Int#
I# Int#
タプル
タプルの高速化
➜ UnboxedTuples(108頁)
自作データ型の高速化
正格性フラグ
data T = T !Int
フラグ(!)の付いた型引数は正格評価される
✔ 受け取ったその場で評価
✔ 遅延評価ならではのデメリットは解消される
自作データ型の高速化
正格性フラグ
data T = T !Int
フラグ(!)の付いた型引数は正格評価される
❌ その値はデータ生成時に直ちに
渡されなければならない
❌ その型を部分適用できなくなる
自作データ型の高速化
正格性フラグ
関数に付与する場合
➜ BangPatterns(148頁)
自作データ型の高速化
標準にあるハッシュ付きの型は Unpack 可能
Int, Integer, Float, Double, Char, Word[N],
Int[N]
これらはライブラリではただの Unpack 可能な型
➜ プリミティブな値は処理系が保持
自作データ型の高速化
標準にあるハッシュ付きの型は Unpack 可能
data T a = T {-# Unpack #-} !Int
T Int#
プリミティブな値がそのまま型引数に収まる
✔ 計算量とメモリ消費量が減る
✔ 生の値なので遅延評価不可
(正格性フラグ必須)
ただのバイナリ
自作データ型の高速化
標準にあるハッシュ付きの型は Unpack 可能
data T a = T {-# Unpack #-} !Int
T Int#
プリミティブな値がそのまま型引数に収まる
❌ 構築子が 1 つだけの型に限る
❌ 通常の型と同じようには使えない
ただのバイナリ
自作データ型の高速化
標準にあるハッシュ付きの型は Unpack 可能
data T a = T {-# Unpack #-} !Int
T Int#
プリミティブな値がそのまま型引数に収まる
❌ 複数あると処理系が判断できない
❌ 通常の型はポインタであると期待される
ただのバイナリ
自作データ型の高速化
標準にあるハッシュ付きの型は Unpack 可能
data T a = T {-# Unpack #-} !Int
T Int#
プリミティブな値がそのまま型引数に収まる
❌ 複数あると処理系が判断できない
❌ 許してしまうと GC の対象になり、
厄介なバグを生みやすくなる
ただのバイナリ
自作データ型の高速化
標準にあるハッシュ付きの型は Unpack 可能
data T a = T {-# Unpack #-} !Int
T Int#
プリミティブな値がそのまま型引数に収まる
❌ 複数あると処理系が判断できない
⚠ 不本意な再ボックス化を防ぐために
最適化オプションを付けるべき
ただのバイナリ
型クラスの仕組み
その正体は辞書
型クラスへの依存(もとい制約)情報は
辞書型のデータ構造によって管理される
型クラスの仕組み
その正体は辞書
:: C a => a
1. C a という制約が導入されて、
2. C a の情報を持つ辞書に型 a の値が適用される
型クラスの仕組み
その正体は辞書
:: C a => a
⚠ 型変数は、注釈中のいずれかのデータ型に
必ず到達できなければならない
型クラスの仕組み
その正体は辞書
:: C a => Hoge ❌
➜ C a だけではインスタンスを特定できない
型クラスの仕組み
その正体は辞書
⚠ インタプリタ(一般に GHCi)では遅い
➜ 制約の辞書も逐次生成される
➜ コンパイル、しよう(提案)
競技プログラミングでの Haskell
速度にシビアな問題では死ぬ
✔ 主に TLE で。
➜ 標準の文字列や List 等では間に合わない
問題がある
➜ それを埋め合わせるライブラリが使えない
➜ そもそも型の構造的に辛い…
競技プログラミングでの Haskell
速度にシビアな問題では死ぬ
対策
✔ 言語拡張を導入(詳細は後述)
➜ UnboxedTuples
➜ OverloadedStrings(※)
➜ OverloadedLists(※)
➜ BangPatterns
競技プログラミングでの Haskell
速度にシビアな問題では死ぬ
※のある拡張は競プロでは使用不可
bytestring も text も vector も競プロの
サイト側では用意されていない…
競技プログラミングでの Haskell
Haskell が使える競プロサービス
AtCoder
✔ GHC 7.8 以降
Codeforces
✔ GHC 7.8 以降
他
❌ (GHC がインストールされて)ないです…
知らないと損する言語拡張たち
107頁 … リテラルを置き換える
117頁 … 計算量を削減する
120頁 … データ型の表現力を向上する
122頁 … 型クラスの表現力を向上する
148頁 … 評価戦力を切り替える
リテラルを置き換える
Overloaded Strings
✔ 文字列(文字のリスト) を IsString の
インスタンスを持つ別の何かに昇格
例) ByteString, Text
IsString さえ実装されていればどんな型でもよい
リテラルを置き換える
Overloaded Strings
ByteString の例
instance IsString ByteString where
fromString = packChars
文字列を packChars に丸投げする
リテラルを置き換える
Overloaded Strings
Text の例
instance IsString Text where
fromString = pack
文字列を pack に丸投げする
リテラルを置き換える
Overloaded Strings
Data.ByteString を import してると
"Hello" :: ByteString
Data.Text を import してると
"Hello" :: Text
リテラルを置き換える
Overloaded Lists
✔ 何らかの List を IsList のインスタンスを持つ
別の何かに昇格
例) vector
IsList さえ実装されていればどんな型でもよい
リテラルを置き換える
Overloaded Lists
Vector の例
instance Ext.IsList (Vector a) where
type Item (Vector a) = a
fromList = fromList
fromListN = fromListN
toList = toList
リテラルを置き換える
Overloaded Lists
Vector の例
type Item (Vector a) = a
Item (Vector a) という型の組み合わせを型 a
として扱わせる言語拡張(ここでは触れない)
See: 7.7 Type families - The User's Guide
リテラルを置き換える
Overloaded Lists
Vector の例
fromList = fromList
List を Vector.fromList に丸投げ
リテラルを置き換える
Overloaded Lists
Vector の例
fromList = fromListN
List を Vector.fromListN に丸投げ
(List の最初の N 要素だけを Vector に入れる)
リテラルを置き換える
Overloaded Lists
Vector の例
toList = toList
Vector を List に変換する
計算量を削減する
Unboxed Tuples
Tuple からタグ(ポインタ部分)を取り除く
➜ ただの限定的な連続領域になる
➜ ポインタを挟まず、要素がスタックや
レジスタに直接置かれる
➜ Unpack されていない要素は通常通り
遅延評価される
計算量を削減する
Unboxed Tuples
Tuple からタグ(ポインタ部分)を取り除く
❌ (多層的な)型や関数の引数には渡せない
➜ 型ではない。
➜ ポインタを持っていない
➜ 引数ではない部分でなら問題ない
(返り値にする時や case 式など)
計算量を削減する
Unboxed Tuples
(Int, Int)
(,) P P
I# Int# I# Int#
(# Int, Int #)
I# Int# I# Int#
連続した領域として
扱われる
データ型の表現力を向上する
GADTs
データコンストラクタにも関数と同じ型注釈を
使えるようにする
data T a = T1 | T2 a (T a)
➜ data T a where
T1 :: T a
T2 :: a -> T a -> T a
データ型の表現力を向上する
GADTs
データコンストラクタにも関数と同じ型注釈を使え
るようにする
✔ 構造がネストするコンストラクタも楽に
定義できるようになる
やったぜ。
型クラスの表現力を向上する
Multi Param Type Classes
型クラスに複数の型変数を許可する
➜ メソッドが複数の異なるインスタンスを
受け取れるようになる
class C a b where
f :: a -> b -> b
型クラスの表現力を向上する
Functional Dependencies
型変数の関係性を明示する
➜ ある型が決まれば別の型も一意に決まる と
いう(依存)関係
class C a b | a -> b where
型クラスの表現力を向上する
Flexible Instances
instance 宣言のルールを緩和する
➜ より柔軟にインスタンスを実装できる
型クラスの表現力を向上する
Flexible Instances
通常時のルール
✔ 1 つの型クラスにつき型変数は 1 つまで
✔ 型変数の重複は許されない
✔ 制約は型変数にのみ与えられる
✔ 実装は必ずしなければならない
型クラスの表現力を向上する
Flexible Instances
拡張導入後のルール
➜ 多変数型クラスの実装を与えてもよい
➜ 型変数は重複していてもよい
➜ 代数的データ型を混ぜてもよい
➜ 宣言のみであってもよい
型クラスの表現力を向上する
Flexible Instances
拡張導入後のルール
✔ instance C a b where ...
✔ instance C a a where ...
✔ instance C a Int where ...
✔ instance C a b (=> ...)
型クラスの表現力を向上する
Flexible Instances
拡張導入後のルール
✔ 型シノニムも宣言に書ける
data T a = T1 | T2 a (T a)
type TT = T Int
instance Eq TT where ...
型クラスの表現力を向上する
Flexible Instances
注意点
⚠ 柔軟化した分、処理系は実装を
特定しにくくなる
型クラスの表現力を向上する
Flexible Instances
例1
class C a b
instance C a Int
instance C Int b
a と b のどちらに Int があっても特定できてしまう
型クラスの表現力を向上する
Flexible Instances
例2
class C a b
instance C Int b
instance C Int [b]
多相型なので一番目の b にも List があり得る
型クラスの表現力を向上する
Flexible Contexts
制約の文法に FlexibleInstance と同じ緩和を適用
する
型クラスの表現力を向上する
Flexible Contexts
⚠ 型変数に言及しなくてよい注釈は存在しない
❌ f :: C a b => Int
❌ f :: C a b => a -> Int
型クラスの表現力を向上する
Flexible Contexts
✔ それ以外は Flexible Instances と同様に書ける
➜ f :: C a b => a -> b -> b
➜ f :: C a a => a -> a -> a
➜ f :: C a (T b) => a -> a -> T b
➜ f :: C a TT => a -> a -> TT
型クラスの表現力を向上する
Overlapping Instances
特定可能なインスタンスの定義が複数ある場合
に、特定先を 1 つに絞らせる
型クラスの表現力を向上する
Overlapping Instances
⚠ 最も特殊性の高い(※)インスタンスが
1 つ以上存在している必要がある。
(※具体的に型が決められていること)
型クラスの表現力を向上する
Overlapping Instances
次のような制約のある注釈を考える
:: C Int Int -> Int -> Int -> a
型クラスの表現力を向上する
Overlapping Instances
以下のインスタンスが定義されているとする
instance C a Int
instance C Int b
instance C Int Int
型クラスの表現力を向上する
Overlapping Instances
この内、最も特殊性が高いのは茶色の定義
instance C Int b
instance C a Int
instance C Int Int
型クラスの表現力を向上する
Overlapping Instances
よって、
:: C Int Int -> Int -> Int -> a
という制約に対して
instance C Int Int
の定義がマッチされる
型クラスの表現力を向上する
Overlapping Instances
⚠ 特殊性の高いインスタンスがひとつもないと
判断された場合はエラーになる
型クラスの表現力を向上する
Overlapping Instances
instance C Int b
instance C a Int
だけだと特定のしようがない…(エラー)
型クラスの表現力を向上する
Incoherent Instances
特殊性のあるインスタンスが 1 つも
見つからなかった場合に、最もパターンの近い
インスタンスを選ばせる
型クラスの表現力を向上する
Incoherent Instances
:: C Int Int -> Int -> Int -> a
という制約に最も適合するインスタンスは
instance C Int Int
だが、これがない場合は
型クラスの表現力を向上する
Incoherent Instances
instance C Int b
instance C a Int
のいずれかを選択させる
型クラスの表現力を向上する
Incoherent Instances
⚠ どのインスタンスが選ばれるのかは、制約を
与えられた関数が呼び出されるまで
わからない
➜ インスタンスの選択を遅延させている
➜ 同じ制約のつもりでも違うインスタンスを
選択される可能性がある
型クラスの表現力を向上する
Incoherent Instances
✔ 複数適合しうるインスタンスをなるべく
書かないようにすることが大事
評価戦略を切り替える
Bang Patterns
関数の引数にも正格性フラグを付与できるように
する
f !x = x * 2
この関数の引数 x は正格評価される
評価戦略を切り替える
Bang Patterns
⚠ 当然ながら遅延評価ではないので、部分適用は
できない
FFIの話
151頁 … 呼び出せるプログラミング言語
154頁 … 呼び出し方
156頁 … Haskell での型の扱い
158頁 … ByteString から見る実装例
160頁 … hmatrix から見る実装例
呼び出せるプログラミング言語
対応状況
C
✔ 標準で使える
C++
▲ extern C 必須
❌ class や template は使用不可
(C と共通する部分のみ使用可)
呼び出せるプログラミング言語
対応状況
Java
✔ java-bridge があるが…
➜ 最近更新されてない…
➜ JNI と闘う覚悟はあるか?
(俺はない(´・_・`))
呼び出せるプログラミング言語
対応状況
.NET
✔ hs-dotnet があるが…
➜ 最近更新されてない…
➜ 恐らく開発自体が止まっている…
呼び出し方
構文(import)
foreign import callconv impent var :: ftype
callconv :=
ccall | stdcall | cplusplus | jvm | dotnet
impent := [string]
(呼び出すヘッダの名前と関数の名前。スペース区切り。なくてもよい)
呼び出し方
構文(export)
foreign export callconv expent var :: ftype
callconv :=
ccall | stdcall | cplusplus | jvm | dotnet
expent := [string]
(呼び出すヘッダの名前と関数の名前。スペース区切り。なくてもよい)
Haskell での型の扱い
型対応表
Haskell → C C → Haskell
CInt HsInt
CFloat HsFloat
CDouble HsDouble
Bool HsBool
Haskell での型の扱い
型対応表
Haskell → C C → Haskell
Ptr a * p
(ポインタ)
FunPtr a int (*p)(int)
(関数ポインタ)
ByteString から見る実装例
C の型を操作するので unsafe
foreign import ccall unsafe "string.h memchr"
c_memchr :: Ptr Word8 -> CInt -> CSize
-> IO (Ptr Word8)
ByteString から見る実装例
C の型を操作するので unsafe
memchr :: Ptr Word8 -> Word8 -> CSize
-> IO (Ptr Word8)
memchr p w s =
c_memchr p (fromIntegral w) s
hmatrix から見る実装例
行列演算ライブラリ
foreign import ccall unsafe "sort_indexD"
c_sort_indexD
:: CV Double (CV CInt (IO CInt))
C と Haskell の間を往復するのでオーバーヘッドが
すごいらしい…
(まだ使ったことがないので詳しくはなんとも…)
おまけ
162頁 … あると便利な言語拡張たち
171頁 … CPP
あると便利な言語拡張たち
BinaryLiterals
二進数による数値表現を可能にする
0b1010 -> 10(10進数)
あると便利な言語拡張たち
LambdaCase
無名関数の要領で case 式を書ける
(case 式に渡すデータの名前を省略できる)
case
p1 -> e1
p2 -> e1
....
あると便利な言語拡張たち
MagicHash
リテラルや型コンストラクタに ハッシュ(#)を使う
ことを許可する
✔ ハッシュ(#)自体には特に意味はない
✔ 慣習的に内部にプリミティブな値を
持っている型に付与されている
あると便利な言語拡張たち
MagicHash
リテラルや型コンストラクタにハッシュ(#)を使う
ことを許可する
'x'# Char➜ #
"foo"# Addr➜ #
3# Int➜ #
3## Word➜ #
あると便利な言語拡張たち
ParallelListComp
複数のリストを同時に内包表記できる
[(x, y) | x <- xs | y <- ys]
これは
zip xs ys
と同じことをしている
あると便利な言語拡張たち
ParallelListComp
お馴染みフィボナッチ数列
fibs =
0 : 1 : [a + b | a <- fibs | b <- tail fibs]
これは
fibs = 0 : 1 : zipWith (+) fibs (tail fibs)
と同じ
あると便利な言語拡張たち
PatternGuards
引数のパターンマッチの柔軟性が増す
通常
f :: Int -> Bool
f x
| n <= x && x <= m = ...
| otherwise = ...
あると便利な言語拡張たち
PatternGuards
引数のパターンマッチの柔軟性が増す
複数の条件を同時に書ける
f :: Int -> Bool
f x
| n <= x && x <= m, x >= n * 100 = ...
| otherwise = ...
あると便利な言語拡張たち
PatternGuards
引数のパターンマッチの柔軟性が増す
これは(||)を適用してるのと同じ
f :: Int -> Bool
f x
| n <= x && x <= m || x >= n * 100 = ...
| otherwise = ...
CPP
実は C 由来のプリプロセッサを書ける
GHC の時のみそのコードが動くようにする
{-# LANGUAGE CPP #-}
#ifdef __GLASGOW_HASKELL__
-- Some Codes Here
#endif
CPP
実は C 由来のプリプロセッサを書ける
GHC の時のみそのコードが動くようにする
{-# LANGUAGE CPP #-}
#ifdef __GLASGOW_HASKELL__
-- Some Codes Here
#endif
CPP
実は C 由来のプリプロセッサを書ける
GHC の特定のバージョンでのみそのコードが動く
ようにする
{-# LANGUAGE CPP #-}
#if __GLASGOW_HASKELL__==780
-- Some Codes Here
#endif
おしまい
話したいことまだまだたくさん
❌ 時間足りない
❌ 話もどんどん複雑化
➜ またの機会に話そうと思う
(機会がなければその内 Qiita に投稿する)
おしまい
───See You Again!

More Related Content

What's hot

オブジェクト指向できていますか?
オブジェクト指向できていますか?オブジェクト指向できていますか?
オブジェクト指向できていますか?Moriharu Ohzu
 
関数型プログラミング入門 with OCaml
関数型プログラミング入門 with OCaml関数型プログラミング入門 with OCaml
関数型プログラミング入門 with OCamlHaruka Oikawa
 
ラムダ計算入門
ラムダ計算入門ラムダ計算入門
ラムダ計算入門Eita Sugimoto
 
Rpn and forth 超入門
Rpn and forth 超入門Rpn and forth 超入門
Rpn and forth 超入門Yoshitaka Seo
 
組み込みでこそC++を使う10の理由
組み込みでこそC++を使う10の理由組み込みでこそC++を使う10の理由
組み込みでこそC++を使う10の理由kikairoya
 
Scala 初心者が米田の補題を Scala で考えてみた
Scala 初心者が米田の補題を Scala で考えてみたScala 初心者が米田の補題を Scala で考えてみた
Scala 初心者が米田の補題を Scala で考えてみたKazuyuki TAKASE
 
ホモトピー型理論入門
ホモトピー型理論入門ホモトピー型理論入門
ホモトピー型理論入門k h
 
圏論とHaskellは仲良し
圏論とHaskellは仲良し圏論とHaskellは仲良し
圏論とHaskellは仲良しohmori
 
すごい配列楽しく学ぼう
すごい配列楽しく学ぼうすごい配列楽しく学ぼう
すごい配列楽しく学ぼうxenophobia__
 
Freer Monads, More Extensible Effects
Freer Monads, More Extensible EffectsFreer Monads, More Extensible Effects
Freer Monads, More Extensible EffectsHiromi Ishii
 
今から始める Lens/Prism
今から始める Lens/Prism今から始める Lens/Prism
今から始める Lens/PrismNaoki Aoyama
 
Where狙いのキー、order by狙いのキー
Where狙いのキー、order by狙いのキーWhere狙いのキー、order by狙いのキー
Where狙いのキー、order by狙いのキーyoku0825
 
LR parsing
LR parsingLR parsing
LR parsingichikaz3
 
リッチなドメインモデル 名前探し
リッチなドメインモデル 名前探しリッチなドメインモデル 名前探し
リッチなドメインモデル 名前探し増田 亨
 
磯野ー!関数型言語やろうぜー!
磯野ー!関数型言語やろうぜー!磯野ー!関数型言語やろうぜー!
磯野ー!関数型言語やろうぜー!Ra Zon
 
Domain Modeling Made Functional (DevTernity 2022)
Domain Modeling Made Functional (DevTernity 2022)Domain Modeling Made Functional (DevTernity 2022)
Domain Modeling Made Functional (DevTernity 2022)Scott Wlaschin
 
謎の言語Forthが謎なので実装した
謎の言語Forthが謎なので実装した謎の言語Forthが謎なので実装した
謎の言語Forthが謎なので実装したt-sin
 

What's hot (20)

オブジェクト指向できていますか?
オブジェクト指向できていますか?オブジェクト指向できていますか?
オブジェクト指向できていますか?
 
関数型プログラミング入門 with OCaml
関数型プログラミング入門 with OCaml関数型プログラミング入門 with OCaml
関数型プログラミング入門 with OCaml
 
Plan 9のお話
Plan 9のお話Plan 9のお話
Plan 9のお話
 
ラムダ計算入門
ラムダ計算入門ラムダ計算入門
ラムダ計算入門
 
Rpn and forth 超入門
Rpn and forth 超入門Rpn and forth 超入門
Rpn and forth 超入門
 
Monad tutorial
Monad tutorialMonad tutorial
Monad tutorial
 
組み込みでこそC++を使う10の理由
組み込みでこそC++を使う10の理由組み込みでこそC++を使う10の理由
組み込みでこそC++を使う10の理由
 
Scala 初心者が米田の補題を Scala で考えてみた
Scala 初心者が米田の補題を Scala で考えてみたScala 初心者が米田の補題を Scala で考えてみた
Scala 初心者が米田の補題を Scala で考えてみた
 
ホモトピー型理論入門
ホモトピー型理論入門ホモトピー型理論入門
ホモトピー型理論入門
 
圏論とHaskellは仲良し
圏論とHaskellは仲良し圏論とHaskellは仲良し
圏論とHaskellは仲良し
 
すごい配列楽しく学ぼう
すごい配列楽しく学ぼうすごい配列楽しく学ぼう
すごい配列楽しく学ぼう
 
Freer Monads, More Extensible Effects
Freer Monads, More Extensible EffectsFreer Monads, More Extensible Effects
Freer Monads, More Extensible Effects
 
今から始める Lens/Prism
今から始める Lens/Prism今から始める Lens/Prism
今から始める Lens/Prism
 
Where狙いのキー、order by狙いのキー
Where狙いのキー、order by狙いのキーWhere狙いのキー、order by狙いのキー
Where狙いのキー、order by狙いのキー
 
LR parsing
LR parsingLR parsing
LR parsing
 
リッチなドメインモデル 名前探し
リッチなドメインモデル 名前探しリッチなドメインモデル 名前探し
リッチなドメインモデル 名前探し
 
磯野ー!関数型言語やろうぜー!
磯野ー!関数型言語やろうぜー!磯野ー!関数型言語やろうぜー!
磯野ー!関数型言語やろうぜー!
 
Domain Modeling Made Functional (DevTernity 2022)
Domain Modeling Made Functional (DevTernity 2022)Domain Modeling Made Functional (DevTernity 2022)
Domain Modeling Made Functional (DevTernity 2022)
 
謎の言語Forthが謎なので実装した
謎の言語Forthが謎なので実装した謎の言語Forthが謎なので実装した
謎の言語Forthが謎なので実装した
 
圏とHaskellの型
圏とHaskellの型圏とHaskellの型
圏とHaskellの型
 

Similar to これから Haskell を書くにあたって

これから Haskell を書くにあたって
これから Haskell を書くにあたってこれから Haskell を書くにあたって
これから Haskell を書くにあたってTsuyoshi Matsudate
 
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
 
モナドハンズオン前座
モナドハンズオン前座モナドハンズオン前座
モナドハンズオン前座bleis tift
 
思ったほど怖くない! Haskell on JVM 超入門 #jjug_ccc #ccc_l8
思ったほど怖くない! Haskell on JVM 超入門 #jjug_ccc #ccc_l8思ったほど怖くない! Haskell on JVM 超入門 #jjug_ccc #ccc_l8
思ったほど怖くない! Haskell on JVM 超入門 #jjug_ccc #ccc_l8y_taka_23
 
Ekmett勉強会発表資料
Ekmett勉強会発表資料Ekmett勉強会発表資料
Ekmett勉強会発表資料時響 逢坂
 
Introduction to NumPy & SciPy
Introduction to NumPy & SciPyIntroduction to NumPy & SciPy
Introduction to NumPy & SciPyShiqiao Du
 
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
 
Ekmett勉強会発表資料
Ekmett勉強会発表資料Ekmett勉強会発表資料
Ekmett勉強会発表資料時響 逢坂
 
RのffでGLMしてみたけど...
RのffでGLMしてみたけど...RのffでGLMしてみたけど...
RのffでGLMしてみたけど...Kazuya Wada
 
LastaFluteでKotlinをはじめよう
LastaFluteでKotlinをはじめようLastaFluteでKotlinをはじめよう
LastaFluteでKotlinをはじめようShinsuke Sugaya
 
Lisp tutorial for Pythonista : Day 1
Lisp tutorial for Pythonista : Day 1Lisp tutorial for Pythonista : Day 1
Lisp tutorial for Pythonista : Day 1Ransui Iso
 
ZFSのソースコードをチラ見してみる
ZFSのソースコードをチラ見してみるZFSのソースコードをチラ見してみる
ZFSのソースコードをチラ見してみるKoichi Suzuki
 
Scalaプログラミング・マニアックス
Scalaプログラミング・マニアックスScalaプログラミング・マニアックス
Scalaプログラミング・マニアックスTomoharu ASAMI
 
transformer解説~Chat-GPTの源流~
transformer解説~Chat-GPTの源流~transformer解説~Chat-GPTの源流~
transformer解説~Chat-GPTの源流~MasayoshiTsutsui
 
関数型言語&形式的手法セミナー(3)
関数型言語&形式的手法セミナー(3)関数型言語&形式的手法セミナー(3)
関数型言語&形式的手法セミナー(3)啓 小笠原
 
モナドをつくろう
モナドをつくろうモナドをつくろう
モナドをつくろうdico_leque
 

Similar to これから Haskell を書くにあたって (20)

これから Haskell を書くにあたって
これから Haskell を書くにあたってこれから Haskell を書くにあたって
これから Haskell を書くにあたって
 
How wonderful to be (statically) typed 〜型が付くってスバラシイ〜
How wonderful to be (statically) typed 〜型が付くってスバラシイ〜How wonderful to be (statically) typed 〜型が付くってスバラシイ〜
How wonderful to be (statically) typed 〜型が付くってスバラシイ〜
 
モナドハンズオン前座
モナドハンズオン前座モナドハンズオン前座
モナドハンズオン前座
 
思ったほど怖くない! Haskell on JVM 超入門 #jjug_ccc #ccc_l8
思ったほど怖くない! Haskell on JVM 超入門 #jjug_ccc #ccc_l8思ったほど怖くない! Haskell on JVM 超入門 #jjug_ccc #ccc_l8
思ったほど怖くない! Haskell on JVM 超入門 #jjug_ccc #ccc_l8
 
Ekmett勉強会発表資料
Ekmett勉強会発表資料Ekmett勉強会発表資料
Ekmett勉強会発表資料
 
Introduction to NumPy & SciPy
Introduction to NumPy & SciPyIntroduction to NumPy & SciPy
Introduction to NumPy & SciPy
 
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
 
Ekmett勉強会発表資料
Ekmett勉強会発表資料Ekmett勉強会発表資料
Ekmett勉強会発表資料
 
Haskell Lecture 2
Haskell Lecture 2Haskell Lecture 2
Haskell Lecture 2
 
Applicative functor
Applicative functorApplicative functor
Applicative functor
 
RのffでGLMしてみたけど...
RのffでGLMしてみたけど...RのffでGLMしてみたけど...
RのffでGLMしてみたけど...
 
たのしい関数型
たのしい関数型たのしい関数型
たのしい関数型
 
LastaFluteでKotlinをはじめよう
LastaFluteでKotlinをはじめようLastaFluteでKotlinをはじめよう
LastaFluteでKotlinをはじめよう
 
Lisp tutorial for Pythonista : Day 1
Lisp tutorial for Pythonista : Day 1Lisp tutorial for Pythonista : Day 1
Lisp tutorial for Pythonista : Day 1
 
ZFSのソースコードをチラ見してみる
ZFSのソースコードをチラ見してみるZFSのソースコードをチラ見してみる
ZFSのソースコードをチラ見してみる
 
Scalaプログラミング・マニアックス
Scalaプログラミング・マニアックスScalaプログラミング・マニアックス
Scalaプログラミング・マニアックス
 
transformer解説~Chat-GPTの源流~
transformer解説~Chat-GPTの源流~transformer解説~Chat-GPTの源流~
transformer解説~Chat-GPTの源流~
 
関数型言語&形式的手法セミナー(3)
関数型言語&形式的手法セミナー(3)関数型言語&形式的手法セミナー(3)
関数型言語&形式的手法セミナー(3)
 
20180728 halide-study
20180728 halide-study20180728 halide-study
20180728 halide-study
 
モナドをつくろう
モナドをつくろうモナドをつくろう
モナドをつくろう
 

Recently uploaded

業務で生成AIを活用したい人のための生成AI入門講座(社外公開版:キンドリルジャパン社内勉強会:2024年4月発表)
業務で生成AIを活用したい人のための生成AI入門講座(社外公開版:キンドリルジャパン社内勉強会:2024年4月発表)業務で生成AIを活用したい人のための生成AI入門講座(社外公開版:キンドリルジャパン社内勉強会:2024年4月発表)
業務で生成AIを活用したい人のための生成AI入門講座(社外公開版:キンドリルジャパン社内勉強会:2024年4月発表)Hiroshi Tomioka
 
CTO, VPoE, テックリードなどリーダーポジションに登用したくなるのはどんな人材か?
CTO, VPoE, テックリードなどリーダーポジションに登用したくなるのはどんな人材か?CTO, VPoE, テックリードなどリーダーポジションに登用したくなるのはどんな人材か?
CTO, VPoE, テックリードなどリーダーポジションに登用したくなるのはどんな人材か?akihisamiyanaga1
 
クラウドネイティブなサーバー仮想化基盤 - OpenShift Virtualization.pdf
クラウドネイティブなサーバー仮想化基盤 - OpenShift Virtualization.pdfクラウドネイティブなサーバー仮想化基盤 - OpenShift Virtualization.pdf
クラウドネイティブなサーバー仮想化基盤 - OpenShift Virtualization.pdfFumieNakayama
 
デジタル・フォレンジックの最新動向(2024年4月27日情洛会総会特別講演スライド)
デジタル・フォレンジックの最新動向(2024年4月27日情洛会総会特別講演スライド)デジタル・フォレンジックの最新動向(2024年4月27日情洛会総会特別講演スライド)
デジタル・フォレンジックの最新動向(2024年4月27日情洛会総会特別講演スライド)UEHARA, Tetsutaro
 
モーダル間の変換後の一致性とジャンル表を用いた解釈可能性の考察 ~Text-to-MusicとText-To-ImageかつImage-to-Music...
モーダル間の変換後の一致性とジャンル表を用いた解釈可能性の考察  ~Text-to-MusicとText-To-ImageかつImage-to-Music...モーダル間の変換後の一致性とジャンル表を用いた解釈可能性の考察  ~Text-to-MusicとText-To-ImageかつImage-to-Music...
モーダル間の変換後の一致性とジャンル表を用いた解釈可能性の考察 ~Text-to-MusicとText-To-ImageかつImage-to-Music...博三 太田
 
自分史上一番早い2024振り返り〜コロナ後、仕事は通常ペースに戻ったか〜 by IoT fullstack engineer
自分史上一番早い2024振り返り〜コロナ後、仕事は通常ペースに戻ったか〜 by IoT fullstack engineer自分史上一番早い2024振り返り〜コロナ後、仕事は通常ペースに戻ったか〜 by IoT fullstack engineer
自分史上一番早い2024振り返り〜コロナ後、仕事は通常ペースに戻ったか〜 by IoT fullstack engineerYuki Kikuchi
 
AWS の OpenShift サービス (ROSA) を使った OpenShift Virtualizationの始め方.pdf
AWS の OpenShift サービス (ROSA) を使った OpenShift Virtualizationの始め方.pdfAWS の OpenShift サービス (ROSA) を使った OpenShift Virtualizationの始め方.pdf
AWS の OpenShift サービス (ROSA) を使った OpenShift Virtualizationの始め方.pdfFumieNakayama
 
TataPixel: 畳の異方性を利用した切り替え可能なディスプレイの提案
TataPixel: 畳の異方性を利用した切り替え可能なディスプレイの提案TataPixel: 畳の異方性を利用した切り替え可能なディスプレイの提案
TataPixel: 畳の異方性を利用した切り替え可能なディスプレイの提案sugiuralab
 

Recently uploaded (8)

業務で生成AIを活用したい人のための生成AI入門講座(社外公開版:キンドリルジャパン社内勉強会:2024年4月発表)
業務で生成AIを活用したい人のための生成AI入門講座(社外公開版:キンドリルジャパン社内勉強会:2024年4月発表)業務で生成AIを活用したい人のための生成AI入門講座(社外公開版:キンドリルジャパン社内勉強会:2024年4月発表)
業務で生成AIを活用したい人のための生成AI入門講座(社外公開版:キンドリルジャパン社内勉強会:2024年4月発表)
 
CTO, VPoE, テックリードなどリーダーポジションに登用したくなるのはどんな人材か?
CTO, VPoE, テックリードなどリーダーポジションに登用したくなるのはどんな人材か?CTO, VPoE, テックリードなどリーダーポジションに登用したくなるのはどんな人材か?
CTO, VPoE, テックリードなどリーダーポジションに登用したくなるのはどんな人材か?
 
クラウドネイティブなサーバー仮想化基盤 - OpenShift Virtualization.pdf
クラウドネイティブなサーバー仮想化基盤 - OpenShift Virtualization.pdfクラウドネイティブなサーバー仮想化基盤 - OpenShift Virtualization.pdf
クラウドネイティブなサーバー仮想化基盤 - OpenShift Virtualization.pdf
 
デジタル・フォレンジックの最新動向(2024年4月27日情洛会総会特別講演スライド)
デジタル・フォレンジックの最新動向(2024年4月27日情洛会総会特別講演スライド)デジタル・フォレンジックの最新動向(2024年4月27日情洛会総会特別講演スライド)
デジタル・フォレンジックの最新動向(2024年4月27日情洛会総会特別講演スライド)
 
モーダル間の変換後の一致性とジャンル表を用いた解釈可能性の考察 ~Text-to-MusicとText-To-ImageかつImage-to-Music...
モーダル間の変換後の一致性とジャンル表を用いた解釈可能性の考察  ~Text-to-MusicとText-To-ImageかつImage-to-Music...モーダル間の変換後の一致性とジャンル表を用いた解釈可能性の考察  ~Text-to-MusicとText-To-ImageかつImage-to-Music...
モーダル間の変換後の一致性とジャンル表を用いた解釈可能性の考察 ~Text-to-MusicとText-To-ImageかつImage-to-Music...
 
自分史上一番早い2024振り返り〜コロナ後、仕事は通常ペースに戻ったか〜 by IoT fullstack engineer
自分史上一番早い2024振り返り〜コロナ後、仕事は通常ペースに戻ったか〜 by IoT fullstack engineer自分史上一番早い2024振り返り〜コロナ後、仕事は通常ペースに戻ったか〜 by IoT fullstack engineer
自分史上一番早い2024振り返り〜コロナ後、仕事は通常ペースに戻ったか〜 by IoT fullstack engineer
 
AWS の OpenShift サービス (ROSA) を使った OpenShift Virtualizationの始め方.pdf
AWS の OpenShift サービス (ROSA) を使った OpenShift Virtualizationの始め方.pdfAWS の OpenShift サービス (ROSA) を使った OpenShift Virtualizationの始め方.pdf
AWS の OpenShift サービス (ROSA) を使った OpenShift Virtualizationの始め方.pdf
 
TataPixel: 畳の異方性を利用した切り替え可能なディスプレイの提案
TataPixel: 畳の異方性を利用した切り替え可能なディスプレイの提案TataPixel: 畳の異方性を利用した切り替え可能なディスプレイの提案
TataPixel: 畳の異方性を利用した切り替え可能なディスプレイの提案
 

これから Haskell を書くにあたって