e 大橋 賢人 [ O H A S H I K e n t ] : c o m p a n y 株式会社オプト テクノロジー 開発2部 : g i t h u b @ l a g e n o r h y n q u e : t w i t t e r @ l a g e n o r h y n q u e : l a n g u a g e s [ P y t h o n H a s k e l l C l o j u r e S c a l a E n g l i s h f r a n ç a i s D e u t s c h р у с с к и й ] : i n t e r e s t s [ プログラミング 語学 数学] )
できる型クラス(type class)。 F[A] => (A => F[B]) => F[B] 型クラスFunctor, Applicative の上位互換。 / / s c a l a z . M o n a d t r a i t M o n a d [ F [ _ ] ] e x t e n d s A p p l i c a t i v e [ F ] w i t h B i n d [ F ] { a b s t r a c t d e f b i n d [ A , B ] ( f a : F [ A ] ) ( f : ( A ) ⇒ F [ B ] ) : F [ B ] a b s t r a c t d e f p o i n t [ A ] ( a : ⇒ A ) : F [ A ] . . . } - - H a s k e l l c l a s s A p p l i c a t i v e m = > M o n a d m w h e r e ( > > = ) : : f o r a l l a b . m a - > ( a - > m b ) - > m b r e t u r n : : a - > m a . . .
=> F[B] にあたる。 s c a l a z . F u n c t o r . m a p v a l n : O p t i o n [ I n t ] = S o m e ( 1 ) v a l f : I n t = > S t r i n g = x = > x . t o S t r i n g / / O p t i o n # m a p n . m a p ( f ) / / O p t i o n # f l a t M a p による実装 n . f l a t M a p { a = > S o m e ( f ( a ) ) } / / f o r 式による実装 f o r { a < - n } y i e l d f ( a )
F[A => B] => F[B] , にあたる。 s c a l a z . A p p l y . a ps c a l a z . s y n t a x . A p p l y O p s . < * > v a l n : O p t i o n [ I n t ] = S o m e ( 1 ) v a l f : O p t i o n [ I n t = > S t r i n g ] = S o m e ( x = > x . t o S t r i n g ) / / O p t i o n # f l a t M a p , O p t i o n # m a p による実装 n . f l a t M a p { a = > f . m a p { g = > g ( a ) } } / / f o r 式による実装 f o r { a < - n g < - f } y i e l d g ( a )
b i n d / > > = F[A] => (A => F[B]) => F[B] , にあたる。 s c a l a z . B i n d . b i n ds c a l a z . s y n t a x . B i n d O p s . > > = v a l n : O p t i o n [ I n t ] = S o m e ( 1 ) v a l f : I n t = > O p t i o n [ S t r i n g ] = x = > S o m e ( x . t o S t r i n g ) / / O p t i o n # f l a t M a p n . f l a t M a p ( f ) / / f o r 式による実装 f o r { a < - n b < - f ( a ) } y i e l d b
e c l a s s U s e r ( f i r s t N a m e : O p t i o n [ S t r i n g ] , l a s t N a m e : O p t i o n [ S t r i n g ] ) d e f u s e r N a m e ( u s e r : U s e r ) : O p t i o n [ S t r i n g ] = u s e r m a t c h { c a s e U s e r ( S o m e ( f i r s t ) , S o m e ( l a s t ) ) = > S o m e ( s " $ f i r s t $ l a s t " ) c a s e _ = > N o n e }
a t M a p , etc. を組み合わせる。 c a s e c l a s s U s e r ( f i r s t N a m e : O p t i o n [ S t r i n g ] , l a s t N a m e : O p t i o n [ S t r i n g ] ) d e f u s e r N a m e ( u s e r : U s e r ) : O p t i o n [ S t r i n g ] = u s e r . f i r s t N a m e . f l a t M a p { f i r s t = > u s e r . l a s t N a m e . m a p { l a s t = > s " $ f i r s t $ l a s t " } }
s e c l a s s U s e r ( f i r s t N a m e : O p t i o n [ S t r i n g ] , l a s t N a m e : O p t i o n [ S t r i n g ] ) d e f u s e r N a m e ( u s e r : U s e r ) : O p t i o n [ S t r i n g ] = f o r { f i r s t < - u s e r . f i r s t N a m e l a s t < - u s e r . l a s t N a m e } y i e l d s " $ f i r s t $ l a s t "
s c a l a z . _ , S c a l a z . _ c a s e c l a s s U s e r ( i d : I n t , f i r s t N a m e : O p t i o n [ S t r i n g ] , l a s t N a m e : O p t i o n [ S t r i n g ] ) d e f u s e r R o l e ( i d : I n t ) : E r r o r \ / R o l e = ? ? ? d e f u s e r I n f o ( u s e r : U s e r ) : E r r o r \ / O p t i o n [ S t r i n g ] = u s e r R o l e ( u s e r . i d ) m a t c h { c a s e \ / - ( r o l e ) = > u s e r m a t c h { c a s e U s e r ( _ , S o m e ( f i r s t ) , S o m e ( l a s t ) ) = > \ / - ( S o m e ( s " $ f i r s t $ l a s t : $ r o l e " ) ) c a s e _ = > \ / - ( N o n e ) } c a s e - \ / ( e r r o r ) = > - \ / ( e r r o r ) }
c a l a z . _ , S c a l a z . _ c a s e c l a s s U s e r ( i d : I n t , f i r s t N a m e : O p t i o n [ S t r i n g ] , l a s t N a m e : O p t i o n [ S t r i n g ] ) d e f u s e r R o l e ( i d : I n t ) : E r r o r \ / R o l e = ? ? ? d e f u s e r I n f o ( u s e r : U s e r ) : E r r o r \ / O p t i o n [ S t r i n g ] = u s e r R o l e ( u s e r . i d ) . m a p { r o l e = > u s e r . f i r s t N a m e . f l a t M a p { f i r s t = > u s e r . l a s t N a m e . m a p { l a s t = > s " $ f i r s t $ l a s t : $ r o l e " } } }
r t s c a l a z . _ , S c a l a z . _ c a s e c l a s s U s e r ( i d : I n t , f i r s t N a m e : O p t i o n [ S t r i n g ] , l a s t N a m e : O p t i o n [ S t r i n g ] ) d e f u s e r R o l e ( i d : I n t ) : E r r o r \ / R o l e = ? ? ? d e f u s e r I n f o ( u s e r : U s e r ) : E r r o r \ / O p t i o n [ S t r i n g ] = f o r { r o l e < - u s e r R o l e ( u s e r . i d ) } y i e l d f o r { f i r s t < - u s e r . f i r s t N a m e l a s t < - u s e r . l a s t N a m e } y i e l d s " $ f i r s t $ l a s t : $ r o l e "
p e F [ A ] = ? ? ? / / F とO p t i o n でネストしたモナド v a l f O p t i o n A : F [ O p t i o n [ A ] ] = ? ? ? / / O p t i o n とF を合成したO p t i o n T v a l o p t i o n T F A : O p t i o n T [ F , A ] = ? ? ? / / O p t i o n v a l o p t i o n A : O p t i o n [ A ] = ? ? ? / / F v a l f A : F [ A ] = ? ? ? / / F [ O p t i o n [ A ] ] → O p t i o n T [ F , A ] O p t i o n T . o p t i o n T ( f O p t i o n A ) / / O p t i o n T [ F , A ] → F [ O p t i o n [ A ] ] o p t i o n T F A . r u n / / O p t i o n [ A ] → F [ O p t i o n [ A ] ] → O p t i o n T [ F , A ] O p t i o n T . o p t i o n T ( o p t i o n A . p o i n t [ F ] ) / / F [ A ] → O p t i o n T [ F , A ] f A . l i f t M [ O p t i o n T ]
a z . _ , S c a l a z . _ c a s e c l a s s U s e r ( i d : I n t , f i r s t N a m e : O p t i o n [ S t r i n g ] , l a s t N a m e : O p t i o n [ S t r i n g ] ) d e f u s e r R o l e ( i d : I n t ) : E r r o r \ / R o l e = ? ? ? t y p e E r r o r O r R e s u l t [ + A ] = E r r o r \ / A d e f u s e r I n f o ( u s e r : U s e r ) : E r r o r \ / O p t i o n [ S t r i n g ] = ( f o r { r o l e < - u s e r R o l e ( u s e r . i d ) . l i f t M [ O p t i o n T ] f i r s t < - O p t i o n T . o p t i o n T ( u s e r . f i r s t N a m e . p o i n t [ E r r o r O r R e s u l t ] ) l a s t < - O p t i o n T . o p t i o n T ( u s e r . l a s t N a m e . p o i n t [ E r r o r O r R e s u l t ] ) } y i e l d s " $ f i r s t $ l a s t : $ r o l e " ) . r u n
a z . _ , S c a l a z . _ c a s e c l a s s U s e r ( i d : I n t , f i r s t N a m e : O p t i o n [ S t r i n g ] , l a s t N a m e : O p t i o n [ S t r i n g ] ) d e f u s e r R o l e ( i d : I n t ) : E r r o r \ / R o l e = ? ? ? t y p e E r r o r O r R e s u l t [ + A ] = E r r o r \ / A d e f f r o m O p t i o n [ A ] ( a : O p t i o n [ A ] ) : O p t i o n T [ E r r o r O r R e s u l t , A ] = O p t i o n T . o p t i o n T ( a . p o i n t [ E r r o r O r R e s u l t ] ) d e f f r o m E i t h e r [ A ] ( a : E r r o r O r R e s u l t [ A ] ) : O p t i o n T [ E r r o r O r R e s u l t , A ] = a . l i f t M [ O p t i o n T ] d e f u s e r I n f o ( u s e r : U s e r ) : E r r o r \ / O p t i o n [ S t r i n g ] = ( f o r { r o l e < - u s e r R o l e ( u s e r . i d ) ▹ f r o m E i t h e r f i r s t < - u s e r . f i r s t N a m e ▹ f r o m O p t i o n l a s t < - u s e r . l a s t N a m e ▹ f r o m O p t i o n } y i e l d s " $ f i r s t $ l a s t : $ r o l e " ) . r u n
F [ _ ] , A ] のF [ _ ] * - > * \ / [ + A , + B ] * - > * - > * / / 方法1 : t y p e a l i a s する t y p e E r r o r O r R e s u l t [ + A ] = E r r o r \ / A O p t i o n T [ E r r o r O r R e s u l t , A ] / / 方法2 : インラインでt y p e a l i a s する( t y p e l a m b d a ) O p t i o n T [ ( { t y p e λ [ + α ] = E r r o r \ / α } ) # λ , A ] / / 方法3 : コンパイラプラグインK i n d P r o j e c t o r を利用する O p t i o n T [ E r r o r \ / + ? , A ]