module Test where


import           Control.Applicative ((<$>))
import qualified Data.Stream as S
import           Data.Stream         (Stream)
import qualified Data.Vector as V


-- Vector stuff

type V = V.Vector Integer

-- Inner product.
inp :: V -> V -> Integer
inp a b = V.foldl' (+) 0 (V.zipWith (*) a b)

-- Stream stuff

instance Monad Stream where
  return = S.stream . return
  (>>=) = flip S.concatMap

-- Generating vectors

small :: Stream V
small = go [] 8 where
  go :: [Integer] -> Integer -> Stream V
  go xs 1 = return $ V.fromList xs
  go xs n = do
    x <- S.stream [-1,0,0,1]
    go (x : xs) (n - 1)

big :: Stream (V,V)
big = do
  v <- small
  w <- small
  return (v,w)

-- Main program

produce :: Stream Integer
produce = S.filter (== 4) $ uncurry inp <$> big

consume :: Stream Integer -> Integer
consume = S.foldl' (+) 0

main :: IO ()
main = print (consume produce)
