1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
|
import Data.List (foldl', unfoldr)
import Control.Applicative
import qualified Data.ByteString.Lazy.Char8 as B
import qualified Data.Vector.Unboxed as V
main = fmap readIntsV (B.readFile "ints.txt") >>= print . foldV allThree
where allThree = Three <$> length_ <*> sum_ <*> maximum_
data Three = Three !Int !Int !Int deriving Show
data Fold b c where F :: (a -> b -> a) -> !a -> (a -> c) -> Fold b c
data Pair a b = P !a !b
instance Functor (Fold b) where fmap f (F op x g) = F op x (f . g)
instance Applicative (Fold b) where
pure !c = F const () (const c)
(F f x c) <*> (F g y c') = F (comb f g) (P x y) (c *** c')
where comb f g (P a a') !b = P (f a b) (g a' b)
(***) f g (P x y) = f x ( g y)
fold :: Fold b c -> [b] -> c
fold (F f x c) bs = c $ (foldl' f x bs)
foldV :: V.Unbox b => Fold b c -> V.Vector b -> c
foldV (F f x c) bs = c $ (V.foldl' f x bs)
sum_, product_ :: Num a => Fold a a
sum_ = F (+) 0 id
product_ = F (*) 1 id
length_ :: Fold a Int
length_ = F (const . (+1)) 0 id
maximum_ = F max 0 id
readInts = unfoldr $ \bs0 -> case B.readInt bs0 of
Nothing -> Nothing
Just (n,bs2) -> case B.uncons bs2 of
Just (_, bs3) -> Just (n,bs3)
Nothing -> Just (n,B.empty)
readIntsV = V.unfoldr $ \bs0 -> case B.readInt bs0 of
Nothing -> Nothing
Just (n,bs2) -> case B.uncons bs2 of
Just (_, bs3) -> Just (n,bs3)
Nothing -> Just (n,B.empty)
|