{"@context":"https://w3id.org/codemeta/3.0","@type":"SoftwareSourceCode","identifier":"pkg:hackage/streaming","name":"streaming","description":"This package contains two modules, Streaming\nand Streaming.Prelude.\nThe principal module, Streaming.Prelude, exports an elementary streaming prelude focused on\na simple \"source\" or \"producer\" type, namely Stream (Of a) m r.\nThis is a sort of effectful version of\n([a],r) in which successive elements of type a arise from some sort of monadic\naction before the succession ends with a value of type r.\nEverything in the library is organized to make\nprogramming with this type as simple as possible,\nby the simple expedient of making it as close to Prelude\nand Data.List as possible. Thus for example\nthe trivial program\n\nsums the first three valid integers from user input. Similarly,\n\nupper-cases the first two lines from stdin as they arise,\nand sends them to stdout. And so on,\nwith filtering, mapping, breaking, chunking, zipping, unzipping, replicating\nand so forth:\nwe program with streams of Ints or Strings directly as\nif they constituted something like a list. That's because streams really do constitute something\nlike a list, and the associated operations can mostly have the same names.\n(A few, like reverse, don't stream and thus disappear;\nothers like unzip are here given properly streaming formulation for the first time.)\nAnd we everywhere\noppose \"extracting a pure list from IO\",\nwhich is the origin of typical Haskell memory catastrophes.\nBasically any case where you are\ntempted to use mapM, replicateM, traverse or sequence\nwith Haskell lists, you would do better to use something like\nStream (Of a) m r. The type signatures are a little fancier, but\nthe programs themselves are mostly the same. In fact, they are mostly simpler. Thus,\nconsider the trivial demo program mentioned in\nthis SO question\n\nThe new user notices that this exhausts memory, and worries about the efficiency of Haskell IORefs.\nBut of course it exhausts memory! Look what it says!\nThe problem is immediately cured by writing\n\nwhich really does what the other program was meant to do,\nuses no more memory than hello-world, and is simpler anyway, since it\ndoesn't involve the detour of \"extracting a list from IO\". Almost\nevery use of list mapM, replicateM, traverse and sequence produces\nthis problem on a smaller scale. People get used to it, as if it were\ncharacteristic of Haskell programs to use a lot of memory. But in truth\n\"extracting a list or sequence from IO\" is mostly just bad practice pure and simple.\nOf course, mapM, replicateM, traverse and sequence make sense for lists,\nunder certain conditions! But unsafePerformIO also makes sense under\ncertain conditions.\n\nThe Streaming module exports the general type,\nStream f m r, which can be used to stream successive distinct\nsteps characterized by any\nfunctor f, though we are mostly interested in organizing computations\nof the form Stream (Of a) m r. The streaming-IO libraries have\nvarious devices for dealing\nwith effectful variants of [a] or ([a],r) in which the emergence of\nsuccessive elements somehow depends on IO. But it is only with\nthe general type Stream f m r, or some equivalent,\nthat one can envisage (for example) the connected streaming of their\nsorts of stream - as one makes lists of lists in the Haskell\nPrelude and Data.List. One needs some such type if we are\nto express properly streaming equivalents of e.g.\n\nto mention a few obviously desirable operations.\n(This is explained more elaborately in the readme below.)\n\nOne could of course throw something\nlike the present Stream type on top of a prior stream concept: this is how pipes and\npipes-group (which are very much our model here) use FreeT.\nBut once one grasps the iterable stream concept needed to express\nthose functions then one will also see that,\nwith it, one is already in possession of a complete\nelementary streaming library - since one possesses Stream ((,) a) m r\nor equivalently Stream (Of a) m r. This\nis the type of a 'generator' or 'producer' or 'source' or whatever\nyou call an effectful stream of items.\nThe present Streaming.Prelude is thus the simplest streaming library that can replicate anything like the API of the Prelude and Data.List.\n\nThe emphasis of the library is on interoperation; for\nthe rest its advantages are: extreme simplicity, re-use of\nintuitions the user has gathered from mastery of Prelude and\nData.List, and a total and systematic rejection of type synonyms.\nThe two conceptual pre-requisites are some\ncomprehension of monad transformers and some familiarity\nwith 'rank 2 types'. It is hoped that experimentation with this\nsimple material, starting with the ghci examples in Streaming.Prelude,\nwill give people who are new to these concepts some\nintuition about their importance. The most fundamental purpose of the\nlibrary is to express elementary streaming ideas without reliance on\na complex framework, but in a way that integrates transparently with\nthe rest of Haskell, using ideas - e.g. rank 2 types, which are here\nimplicit or explicit in most mapping - that the user can carry elsewhere,\nrather than chaining her understanding to the curiosities of\na so-called streaming IO framework (as necessary as that is for certain purposes.)\n\nSee the\nreadme\nbelow for further explanation, including the examples linked there.\nElementary usage can be divined from the ghci examples in\nStreaming.Prelude and perhaps from this rough beginning of a\ntutorial.\nNote also the\nstreaming bytestring\nand\nstreaming utils\npackages. Questions about usage can be put\nraised on StackOverflow with the tag [haskell-streaming],\nor as an issue on Github, or on the\npipes list\n(the package understands itself as part of the pipes 'ecosystem'.)\n\nThe simplest form of interoperation with\npipes\nis accomplished with this isomorphism:\n\nInteroperation with\nio-streams\nis thus:\n\nWith\nconduit\none might use, e.g.:\n\nThese conversions should never be more expensive than a single \u003e-\u003e or =$=.\nThe simplest interoperation with regular Haskell lists is provided by, say\n\nThe latter of course accumulates the whole list in memory, and is mostly what we are trying\nto avoid. Every use of Prelude.mapM f should be reconceived as using the\ncomposition Streaming.toList_ . Streaming.mapM f . Streaming.each with a view to\nconsidering whether the accumulation required by Streaming.toList_ is really necessary.\n\nHere are the results of some\nmicrobenchmarks\nbased on the\nbenchmarks\nincluded in the machines package:","version":"0.2.4.0","softwareVersion":"0.2.4.0","license":"https://spdx.org/licenses/BSD-3-Clause","codeRepository":"https://github.com/haskell-streaming/streaming","issueTracker":"https://github.com/haskell-streaming/streaming/issues","url":"https://github.com/haskell-streaming/streaming","keywords":["bsd3","data","library","pipes","streaming","Propose Tags"],"programmingLanguage":{"@type":"ComputerLanguage","name":"Haskell"},"maintainer":[{"@type":"Person","name":"OliverCharles"},{"@type":"Person","name":"chessai"},{"@type":"Person","name":"andrewthad"},{"@type":"Person","name":"MichaelThompson"}],"author":[{"@type":"Person","name":"OliverCharles"},{"@type":"Person","name":"chessai"},{"@type":"Person","name":"andrewthad"},{"@type":"Person","name":"MichaelThompson"}],"copyrightHolder":[{"@type":"Person","name":"OliverCharles"},{"@type":"Person","name":"chessai"},{"@type":"Person","name":"andrewthad"},{"@type":"Person","name":"MichaelThompson"}],"dateCreated":"2015-08-14","dateModified":"2023-07-06","datePublished":"2023-07-06","copyrightYear":2015,"downloadUrl":"https://hackage.haskell.org/package/streaming-0.2.4.0/streaming-0.2.4.0.tar.gz","applicationCategory":"hackage","runtimePlatform":"hackage","developmentStatus":"active","sameAs":["https://hackage.haskell.org/package/streaming"],"https://www.w3.org/ns/activitystreams#likes":172,"https://forgefed.org/ns#forks":30}