Last active
November 10, 2015 03:37
-
-
Save erewok/9239cb57834789886f5c to your computer and use it in GitHub Desktop.
Moving Average Test: Uses Conduits
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
name: conduit-test | |
version: 0.1.0.0 | |
synopsis: Initial project template from stack | |
description: Please see README.md | |
homepage: https://gist.github.com/pellagic-puffbomb/9239cb57834789886f5c | |
license: BSD3 | |
license-file: LICENSE | |
author: Erik Aker | |
maintainer: [email protected] | |
-- copyright: | |
category: Web | |
build-type: Simple | |
-- extra-source-files: | |
cabal-version: >=1.10 | |
executable conduit-test | |
hs-source-dirs: src | |
main-is: Main.hs | |
ghc-options: -threaded -rtsopts -with-rtsopts=-N | |
build-depends: base | |
, transformers | |
, mtl | |
, conduit | |
, conduit-combinators | |
, resourcet | |
, containers | |
default-language: Haskell2010 | |
test-suite new-template-test | |
type: exitcode-stdio-1.0 | |
hs-source-dirs: test | |
main-is: Spec.hs | |
build-depends: base | |
, conduit | |
, conduit-combinators | |
, transformers | |
, mtl | |
, resourcet | |
, containers | |
ghc-options: -threaded -rtsopts -with-rtsopts=-N | |
default-language: Haskell2010 | |
source-repository head | |
type: git | |
location: https://gist.github.com/pellagic-puffbomb/9239cb57834789886f5c |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{-# LANGUAGE MultiWayIf #-} | |
module Main where | |
import Control.Monad.IO.Class (liftIO) | |
import Data.Conduit (($$), (=$=), (=$) | |
, Conduit, Sink, Source | |
, await, yield) | |
import qualified Data.Conduit.List as CL | |
import Data.Sequence | |
import Prelude hiding (head, length, drop) | |
averageLen :: Int | |
averageLen = 10 | |
type Size = Int | |
type RunningSum = Int | |
source :: Source IO Int | |
source = CL.sourceList [1..1000] | |
conduit :: RunningSum -> Size -> Seq Int -> Conduit Int IO Int | |
conduit total len sequence = do | |
val <- await | |
case val of | |
Nothing -> return () | |
Just n -> do | |
let newtotal = total + n | |
let newsequence = (|>) sequence n | |
if | length newsequence < len -> conduit newtotal len newsequence | |
| length newsequence == len -> do | |
yield $ newtotal `div` (fromIntegral len) | |
conduit newtotal len newsequence | |
| otherwise -> do | |
let dropFrontTotal = fromIntegral (newtotal - index newsequence 0) | |
let newsequence' = drop 1 newsequence | |
yield $ dropFrontTotal `div` (fromIntegral len) | |
conduit dropFrontTotal len newsequence' | |
-- Using views: to be benchmarked | |
conduitV :: RunningSum -> Size -> Seq Int -> Conduit Int IO Int | |
conduitV total len sequence = do | |
val <- await | |
case val of | |
Nothing -> return () | |
Just n -> do | |
let newtotal = total + n | |
let newsequence = (|>) sequence n | |
if | length newsequence < len -> conduitV newtotal len newsequence | |
| length newsequence == len -> do | |
yield $ newtotal `div` (fromIntegral len) | |
conduitV newtotal len newsequence | |
| otherwise -> do | |
let newSeq = viewl newsequence | |
case newSeq of | |
EmptyL -> return () -- shouldn't happen: we just appended to it above? | |
(a :< seq) -> do | |
let dropFrontTotal = newtotal - a | |
yield $ dropFrontTotal `div` (fromIntegral len) | |
conduitV dropFrontTotal len seq | |
sink :: Sink Int IO () | |
sink = do | |
val <- await | |
case val of | |
Nothing -> return () | |
Just n -> do | |
liftIO $ print n | |
sink | |
main :: IO () | |
main = do | |
let initial = fromList [] | |
source $$ conduitV 0 averageLen initial =$ sink |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Benchmarked with criterion (
whnfIO
?):Using
conduit
on 1..10,000Using
conduitV
on 1..10,000Using
conduit
on 1..100,000Using
conduitV
on 1..100,000