. T y p e s w h e r e d a t a U s e r = U s e r { u s e r N a m e : : S t r i n g } d e r i v i n g ( S h o w , E q , O r d ) d a t a C l i e n t = C l i e n t { c l i e n t U s e r : : U s e r , c l i e n t H a n d l e : : H a n d l e } d e r i v i n g ( S h o w , E q ) d a t a S e r v e r = S e r v e r { s e r v e r U s e r s : : M V a r ( M a p . M a p U s e r C l i e n t ) }
. S e r v e r w h e r e i m p o r t L i n k . T y p e s r u n S e r v e r : : I n t - > I O ( ) r u n S e r v e r p o r t = w i t h S o c k e t s D o $ d o h S e t B u f f e r i n g s t d o u t L i n e B u f f e r i n g s e r v e r < - n e w S e r v e r s o c k < - l i s t e n O n . P o r t N u m b e r . f r o m I n t e g r a l $ p o r t p r i n t f " L i s t e n i n g o n p o r t % d \ n " p o r t f o r e v e r $ d o ( h a n d l e , h o s t , p o r t ' ) < - a c c e p t s o c k p r i n t f " A c c e p t e d c o n n e c t i o n f r o m % s : % s \ n " h o s t ( s h o w p o r t ' ) f o r k I O $ c o n n e c t C l i e n t s e r v e r h a n d l e ` f i n a l l y ` h C l o s e h a n d l e
e n t : : S e r v e r - > H a n d l e - > I O ( ) c o n n e c t C l i e n t s e r v e r h a n d l e = d o h S e t N e w l i n e M o d e h a n d l e u n i v e r s a l N e w l i n e M o d e h S e t B u f f e r i n g h a n d l e L i n e B u f f e r i n g r e a d N a m e w h e r e
I O ( ) r e a d N a m e = d o n a m e < - h G e t L i n e h a n d l e i f n u l l n a m e t h e n r e a d N a m e e l s e d o l e t u s e r = U s e r n a m e o k < - c h e c k A d d C l i e n t s e r v e r u s e r h a n d l e c a s e o k o f N o t h i n g - > d o h P r i n t f h a n d l e " T h e n a m e % s i s i n u s e , p l e a s e c h o o s e a n o t h e r \ n " n a m e r e a d N a m e J u s t c l i e n t - > r u n C l i e n t s e r v e r c l i e n t ` f i n a l l y ` r e m o v e C l i e n t s e r v e r u s e r
i e n t : : S e r v e r - > U s e r - > H a n d l e - > I O ( M a y b e C l i e n t ) c h e c k A d d C l i e n t S e r v e r { . . } u s e r @ U s e r { . . } h a n d l e = m o d i f y M V a r s e r v e r U s e r s $ \ c l i e n t M a p - > i f M a p . m e m b e r u s e r c l i e n t M a p t h e n r e t u r n ( c l i e n t M a p , N o t h i n g ) e l s e d o c l i e n t < - C l i e n t u s e r h a n d l e p r i n t f " N e w u s e r c o n n e c t e d : % s \ n " u s e r N a m e r e t u r n ( M a p . i n s e r t u s e r c l i e n t c l i e n t M a p , J u s t c l i e n t ) r e m o v e C l i e n t : : S e r v e r - > U s e r - > I O ( ) r e m o v e C l i e n t S e r v e r { . . } u s e r = m o d i f y M V a r _ s e r v e r U s e r s $ r e t u r n . M a p . d e l e t e u s e r
. T y p e s w h e r e d a t a C l i e n t = C l i e n t { c l i e n t U s e r : : U s e r , c l i e n t H a n d l e : : H a n d l e , c l i e n t C h a n : : C h a n M e s s a g e } d a t a M e s s a g e = M s g U s e r S t r i n g d e r i v i n g ( S h o w , E q )
. P r o t o c o l w h e r e i m p o r t L i n k . T y p e s p a r s e C o m m a n d : : S t r i n g - > M a y b e M e s s a g e p a r s e C o m m a n d c o m m a n d = c a s e w o r d s c o m m a n d o f " M S G " : u s e r N a m e : m s g - > J u s t $ M s g ( U s e r u s e r N a m e ) ( u n w o r d s m s g ) _ - > N o t h i n g f o r m a t M e s s a g e : : M e s s a g e - > S t r i n g f o r m a t M e s s a g e ( M s g u s e r m s g ) = p r i n t f " M S G % s % s " ( u s e r N a m e u s e r ) m s g
: S e r v e r - > C l i e n t - > I O ( ) r u n C l i e n t S e r v e r { . . } C l i e n t { . . } = f o r e v e r $ d o r < - t r y $ r a c e r e a d C o m m a n d r e a d M e s s a g e c a s e r o f L e f t ( e : : S o m e E x c e p t i o n ) - > p r i n t f " E x c e p t i o n : % s \ n " ( s h o w e ) R i g h t c m - > c a s e c m o f L e f t m c o m m a n d - > c a s e m c o m m a n d o f N o t h i n g - > p r i n t f " C o u l d n o t p a r s e c o m m a n d \ n " J u s t c o m m a n d - > h a n d l e C o m m a n d c o m m a n d R i g h t m e s s a g e - > h a n d l e M e s s a g e m e s s a g e w h e r e
d : : I O ( M a y b e M e s s a g e ) r e a d C o m m a n d = d o c o m m a n d < - h G e t L i n e c l i e n t H a n d l e p r i n t f " < % s > : % s \ n " ( u s e r N a m e c l i e n t U s e r ) c o m m a n d r e t u r n $ p a r s e C o m m a n d c o m m a n d r e a d M e s s a g e : : I O M e s s a g e r e a d M e s s a g e = r e a d C h a n c l i e n t C h a n s e n d M e s s a g e : : M e s s a g e - > I O ( ) s e n d M e s s a g e m e s s a g e = w r i t e C h a n c l i e n t C h a n
a n d : : M e s s a g e - > I O ( ) h a n d l e C o m m a n d ( M s g u s e r m s g ) = c l i e n M a p < - r e a d M V a r s e r v e r U s e r s c a s e M a p . l o o k u p u s e r c l i e n t M a p o f N o t h i n g - > p r i n t f " N o s u c h u s e r : % s \ n " ( u s e r N a m e u s e r ) J u s t c l i e n t - > s e n d M e s s a g e ( M s g c l i e n t U s e r m s g ) c l i e n t h a n d l e M e s s a g e : : M e s s a g e - > I O ( ) h a n d l e M e s s a g e = p r i n t T o H a n d l e c l i e n t H a n d l e . f o r m a t M e s s a g e
> I O b - > I O ( E i t h e r a b ) r a c e i o a i o b = d o m < - n e w E m p t y M V a r b r a c k e t ( f o r k I O ( f m a p L e f t i o a ) ( p u t M V a r m ) ) k i l l T h r e a d $ \ _ - > b r a c k e t ( f o r k I O ( f m a p R i g h t i o b ) ( p u t M V a r m ) ) k i l l T h r e a d $ \ _ - > r e a d M V a r m
. T y p e s w h e r e t y p e U s e r N a m e = S t r i n g t y p e C h a n n e l N a m e = S t r i n g d a t a U s e r = U s e r { u s e r N a m e : : ! U s e r N a m e } d e r i v i n g ( S h o w , E q , O r d ) d a t a C h a n n e l = C h a n n e l { c h a n n e l N a m e : : C h a n n e l N a m e , c h a n n e l U s e r s : : T V a r ( S e t . S e t U s e r ) , c h a n n e l C h a n : : T C h a n M e s s a g e }
= S e r v e r { s e r v e r U s e r s : : M V a r ( M a p . M a p U s e r C l i e n t ) , s e r v e r C h a n n e l s : : T V a r ( M a p . M a p C h a n n e l N a m e C h a n n e l ) } d a t a C l i e n t = C l i e n t { c l i e n t U s e r : : ! U s e r , c l i e n t H a n d l e : : ! H a n d l e , c l i e n t C h a n : : T C h a n M e s s a g e , c l i e n t C h a n n e l C h a n s : : T V a r ( M a p . M a p C h a n n e l N a m e ( T C h a n M e s s a g e ) ) }
e = M s g U s e r S t r i n g | T e l l C h a n n e l N a m e S t r i n g | J o i n C h a n n e l N a m e | L e a v e C h a n n e l N a m e | M s g R e p l y U s e r S t r i n g | T e l l R e p l y C h a n n e l N a m e U s e r S t r i n g | J o i n e d C h a n n e l N a m e U s e r | L e a v e d C h a n n e l N a m e U s e r d e r i v i n g ( S h o w , E q )
r : : a - > S T M ( T V a r a ) r e a d T V a r : : T V a r a - > S T M a w r i t e T V a r : : T V a r a - > a - > S T M ( ) a t o m i c a l l y : : S T M a - > I O a r e t r y : : S T M a
h a n : : S T M ( T C h a n a ) w r i t e T C h a n : : T C h a n a - > a - > S T M ( ) r e a d T C h a n : : T C h a n a - > S T M a o r E l s e : : S T M a - > S T M a - > S T M a
: S e r v e r - > C l i e n t - > I O ( ) r u n C l i e n t S e r v e r { . . } c l i e n t @ C l i e n t { . . } = d o c o m m a n d T h r e a d < - f o r k I O $ r e a d C o m m a n d s r u n ` f i n a l l y ` d o k i l l T h r e a d c o m m a n d T h r e a d c l i e n t C h a n n e l M a p < - r e a d T V a r I O c l i e n t C h a n n e l C h a n s f o r M _ ( M a p . k e y s c l i e n t C h a n n e l M a p ) $ \ c h a n n e l N a m e - > h a n d l e M e s s a g e ( L e a v e c h a n n e l N a m e ) w h e r e
u n = f o r e v e r $ d o r < - t r y . a t o m i c a l l y $ d o c l i e n t C h a n n e l M a p < - r e a d T V a r c l i e n t C h a n n e l C h a n s f o l d r ( o r E l s e . r e a d T C h a n ) r e t r y $ c l i e n t C h a n : M a p . e l e m s c l i e n t C h a n n e l M a p c a s e r o f L e f t ( e : : S o m e E x c e p t i o n ) - > p r i n t f " E x c e p t i o n : % s \ n " ( s h o w e ) R i g h t m e s s a g e - > h a n d l e M e s s a g e m e s s a g e r e a d C o m m a n d s : : I O ( ) r e a d C o m m a n d s = f o r e v e r $ d o c o m m a n d < - h G e t L i n e c l i e n t H a n d l e p r i n t f " < % s > : % s \ n " ( u s e r N a m e c l i e n t U s e r ) c o m m a n d c a s e p a r s e C o m m a n d c o m m a n d o f N o t h i n g - > p r i n t f " C o u l d n o t p a r s e c o m m a n d : % s \ n " c o m m a n d J u s t c - > s e n d M e s s a g e I O c l i e n t c
a g e : : M e s s a g e - > I O ( ) h a n d l e M e s s a g e ( J o i n c h a n n e l N a m e ) = a t o m i c a l l y $ d o c l i e n t C h a n n e l M a p < - r e a d T V a r c l i e n t C h a n n e l C h a n s - - g e t u s e r ' s c h a n n e l s - - i f u s e r h a s n o t a l r e a d y j o i n e d t h e c h a n n e l u n l e s s ( M a p . m e m b e r c h a n n e l N a m e c l i e n t C h a n n e l M a p ) $ d o c h a n n e l M a p < - r e a d T V a r s e r v e r C h a n n e l s - - g e t s e r v e r c h a n n e l s c h a n n e l @ C h a n n e l { c h a n n e l C h a n } < - c a s e M a p . l o o k u p c h a n n e l N a m e c h a n n e l M a p o f J u s t ( c h a n n e l @ C h a n n e l { c h a n n e l U s e r s } ) - > d o - - i f t h e c h a n n e l a l r e a d y e x i s t s o n t h e s e r v e r , a d d u s e r t o i t m o d i f y T V a r ' c h a n n e l U s e r s $ S e t . i n s e r t c l i e n t U s e r r e t u r n c h a n n e l N o t h i n g - > d o - - e l s e c r e a t e a n e w c h a n n e l w i t h t h i s u s e r i n i t a n d a d d i t t o t h e s e r v e r c h a n n e l < - n e w C h a n n e l c h a n n e l N a m e $ S e t . s i n g l e t o n c l i e n t U s e r m o d i f y T V a r ' s e r v e r C h a n n e l s $ M a p . i n s e r t c h a n n e l N a m e c h a n n e l r e t u r n c h a n n e l - - d u p l i c a t e c h a n n e l T C h a n f o r t h i s u s e r a n d a d d i t t o t h e u s e r s ' s c h a n n e l s c l i e n t C h a n n e l C h a n < - d u p T C h a n c h a n n e l C h a n m o d i f y T V a r ' c l i e n t C h a n n e l C h a n s $ M a p . i n s e r t c h a n n e l N a m e c l i e n t C h a n n e l C h a n - - s e n d a J O I N E D m e s s a g e t o t h e c h a n n e l f o r t h i s u s e r t e l l M e s s a g e c h a n n e l $ J o i n e d c h a n n e l N a m e c l i e n t U s e r