, Output Input - ( ). , , {0, 1, 2} 3 {0, 1} 2, , 0 0 1, 1 0 1, 2- 0 1. 2 * 2 * 2 2 3.
+, *, Out In1 + In2= Out In1 * Out In2; :
combiner :: (a -> z, b -> z) -> Either a b -> z
combiner (za, zb) e_ab = case e_ab of Left a -> za a; Right b -> zb b
splitter :: (Either a b -> z) -> (a -> z, b -> z)
splitter z_eab = (\a -> z_eab $ Left a, \b -> z_eab $ Right b)
:
type Processor = Either String Int -> IO ()
? :
- , .
combiner a -> b -> z, , a -> (b -> z) b -> z z. a -> b -> z c -> z, (a, b) -> z, - . - ;
fst split a combined $ Left a. , - yz . combined ( (yz . fst split, yz . snd split)) . Processor, * -> * Functor. - , sum-type.
- Amount types will look more urgent, so they are likely to be more readable. For example, if I give you the template
withProcState p () [Read path1, Apply (map toUpper), Write path2], itβs pretty easy to see that this passes the processor with the commands in upper case 1 to path2. The equivalent of the defining processors will look like procWrite p path2 $ procApply p (map toUpper) $ procRead p path1 ()which is still pretty clear, but not as amazing as in the previous case.
source
share