Re: [Haskell-cafe] simple parsec question
Carlo, Thanks a lot! This looks very promising (though I have to test it for my purpose more in depth). As you mention, the key seems to be the optionMaybe combinator. Thanks for pointing to it. Immanuel 2013/3/5 Carlo Hamalainen carlo.hamalai...@gmail.com On Mon, Mar 4, 2013 at 1:44 AM, Immanuel Normann immanuel.norm...@googlemail.com wrote: I am trying to parse a semi structured text with parsec that basically should identify sections. Each section starts with a headline and has an unstructured content - that's all. Here's my attempt: https://gist.github.com/carlohamalainen/5087207 {-# LANGUAGE FlexibleContexts #-} import Text.Parsec import Control.Applicative hiding ((|),many) -- Example input: {- top 1: some text ... bla top 2: more text ... bla bla -} data Top = Top String deriving (Show) data Content = Content [String] deriving (Show) data Section = Section Top Content deriving (Show) headline = do t - many1 (noneOf :\n) char ':' newline return $ Top t contentLine = do x - many (noneOf :\n) newline return x content = do line - optionMaybe (try contentLine) case line of Just x - do xs - content return (x:xs) _ - return [] section = do h - headline c - Content $ content return $ Section h c main = do x - readFile simple.txt print $ parse (many section) x Example run using your sample data: $ runhaskell Simple.hs Right [Section (Top top 1) (Content [,some text ... bla,]),Section (Top top 2) (Content [,more text ... bla bla,])] Notes: * I had to assume that a content line does not contain a ':', because that is the only way to distinguish a head-line (correct me if I'm wrong). * The key was to use optionMaybe along with try; see the definition of content. * I haven't tested this code on very large inputs. * I slightly changed the definition of Content to have a list of Strings, one for each line. I'm sure this could be altered if you wanted to retain all whitespace. * I am still new to Parsec, so don't take this as the definitive answer ;-) -- Carlo Hamalainen http://carlo-hamalainen.net ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] Haskell + RankNTypes + (forall p. p Char - p Bool) sound?
I was trying to figure out a way to write absurd :: (forall p. p Char - p Bool) - Void using only rank-n types. Someone suggested that Haskell with RankNTypes and a magic primitive of type (forall p. p Char - p Bool) might be sound (disregarding the normal ways to get ⊥, of course). Is that true? Given either TypeFamilies or GADTs, you can write absurd. But it doesn't seem like you can write it with just RankNTypes. (This is related to GeneralizedNewtypeDeriving, which is more or less a version of that magic primitive.) This seems like something that GADTs (/TypeFamilies) give you over Leibniz equality: You can write data Foo a where FooA :: Foo Char FooB :: Void - Foo Bool foo :: Foo Bool - Void foo (FooB x) = x Without any warnings. On the other hand data Bar a = BarA (Is a Char) | BarB (Is a Bool) Void bar :: Bar Bool - Void bar (BarB _ x) = x bar (BarA w) = -- ??? Doesn't seem possible. If it's indeed impossible, what's the minimal extension you would need to add on top of RankNTypes to make it work? GADTs seems way too big. Shachaf ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Haskell syntax/indentation for vim
Here is the crazy idea; instead of having a vim plugin to rule-them-all, why you don't join your efforts and create a plugin which does only indentation for Haskell code? This way, we could have a modular stack and be free to use whatever plugins work for syntax highlighting / unicode syntactic sugar / whatever, but still have a de facto plugin for indenting haskell code in Vim in a smart way :) A.- ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] simple parsec question
Maybe this is something you do not even want to use a parser combinator library for. The package http://hackage.haskell.org/packages/archive/list-grouping/0.1.1/doc/html/Data-List-Grouping.html contains a function breakBefore, so you can write main = do inp - readFile ... let result = map mkSection . breakBefore ((= ':').last)). lines $ inp mkSection (l:ll) = Section (Top l) (Contents ll) Doaitse On Mar 3, 2013, at 16:44 , Immanuel Normann immanuel.norm...@googlemail.com wrote: Hi, I am trying to parse a semi structured text with parsec that basically should identify sections. Each section starts with a headline and has an unstructured content - that's all. For instance, consider the following example text (inside the dashed lines): --- top 1: some text ... bla top 2: more text ... bla bla --- This should be parsed into a structure like this: [Section (Top 1) (Content some text ... bla), Section (Top 1) (Content more text ... bla)] Say, I have a parser headline, but the content after a headline could be anything that is different from what headline parses. How could the section parser making use of headline look like? My idea would be to use the manyTill combinator, but I dont find an easy solution. Many thanks for any hint Immanuel ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Library API design: functional objects VS type classes
Hi Rob, I usually prefer type class approach for early stage of development. Type class approach is more flexible, less works required. One might get a function with lots of constraints, and quite a lot of language extensions may appear, though it works. Once things got settled down, I reconsider API. The type signatures shown in your example:: class FooC a where mkFooC :: IO a readFooC :: a - IO Int incrFooC :: a - IO () and: data FooT a = FooT { readFooT :: IO a , incrFooT :: IO () } Resulting type of 'readFooC' is fixed to 'Int' within the type class. On the other hand, resulting type of 'readFooT' is type variable 'a'. Made slight modification to the type class shown in your example. Changed result type of 'readFooC' to take associated type: http://hpaste.org/83507 Once criteria for comparison I can think is performance. For compilation time, I guess functional object approach give better performance, since some of the works done by compiler are already done manually. Though, I haven't done benchmark of compilation time, and not sure how much interest exist in performance of compilation. For runtime performance, one can do benchmark in its concrete usecase. I suppose, generally, functions defined with type class are slower than functions having concrete type. See SPECIALIZE pragam in GHC[1]. Another criteria I can think is extensibility. Suppose that we want to have new member function, 'incrTwice'. If we have chance to change the source of 'FooC', adding new member function to 'FooC' type class directly is possible, with default function body filled in. class FooC a where type FooCVal a :: * mkFooC :: IO a readFooC :: a - IO (FooCVal a) incrFooC :: a - IO () incrTwiceC :: a - IO () incrTwiceC a = incrFooC a incrFooC a Though, having reasonable default is not always possible. For additional source of inspiration, might worth looking the classic[2], and scrap your type classes article[3]. [1]: http://www.haskell.org/ghc/docs/7.6.1/html/users_guide/pragmas.html#specialize-pragma [2]: http://homepages.inf.ed.ac.uk/wadler/papers/class/class.ps [3]: http://www.haskellforall.com/2012/05/scrap-your-type-classes.html Hope these help. Regards, -- Atsuro On Tue, Mar 5, 2013 at 7:50 AM, Rob Stewart robstewar...@gmail.com wrote: Hi, I have a question about API design for Haskell libraries. It is a simple one: functional object data structures encapsulating mutable state VS type classes encapsulating mutable state Here is a simple example. I present an API: using a type class `FooC`, and aso as a data structure `FooT`. Both are stateful, in the form of an MVar holding an Integer, with an operation `incrFoo` to increment this value by one, and another `readFoo` to read the Integer value. - import Control.Concurrent -- API approach 1: Using type classes class FooC a where mkFooC :: IO a readFooC :: a - IO Int incrFooC :: a - IO () newtype Bar = Bar (MVar Int) instance FooC Bar where mkFooC = newMVar 0 = \i - return $ Bar i readFooC (Bar mv) = readMVar mv incrFooC (Bar mv) = modifyMVar_ mv $ \i - return (i+1) -- API approach 2: Using direct field records data FooT a = FooT { readFooT :: IO a , incrFooT :: IO () } mkBar :: IO (FooT Int) mkBar = do mv - newMVar 0 return FooT { readFooT = readMVar mv , incrFooT = modifyMVar_ mv $ \i - return (i+1) } -- Tests the type class API testTypeClass :: IO () testTypeClass = do bar - mkBar incrFooT bar incrFooT bar i - readFooT bar print i -- prints 2 -- Tests the direct data structure API testDataStruct :: IO () testDataStruct = do bar - (mkFooC :: IO Bar) incrFooC bar incrFooC bar i - readFooC bar print i -- prints 2 With that, I now ask: which is more common? Which is the better API design for a library? The APIs are almost identical. Under what conditions is the type classes preferred over the mutable object style data structure? There are two related resources that provides additional context here, that favour the functional objects approach: - Section 3.4 Mutable Objects in Haskell's Overlooked Object System http://goo.gl/gnZXL - A similar question (data structures vs type classes) in Haskell Antipattern: Existential Typeclass http://lukepalmer.wordpress.com/2010/01/24/haskell-antipattern-existential-typeclass/ Thanks! -- Rob ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] What pattern is this (Something.T - IO a) in Sound.ALSA.Sequencer
* Martin Drautzburg martin.drautzb...@web.de [2013-03-04 21:21:30+0100] On Sunday, 3. March 2013 21:11:21 Roman Cheplyaka wrote: Admittedly, programming with callbacks is not very pleasant. So we have an excellent alternative — the continuation monad transformer! This nested code something1 $ \x - do something2 $ \y - do something3 $ \z - do can be equivalently rewritten as this linear code import Control.Monad.Cont flip runContT return $ do x - ContT something1 y - ContT something2 z - ContT something3 lift $ do ... Mind-blowing. Thanks a lot. Before I dig into the continuation monad transformer, one more question (demonstrating my ignorance): The initialization actually starts with main = (do SndSeq.withDefault SndSeq.Block $ \h - do Client.setName (h :: SndSeq.T SndSeq.DuplexMode) Haskell-Melody Port.withSimple h out (Port.caps [Port.capRead, Port.capSubsRead, Port.capWrite]) (Port.types [Port.typeMidiGeneric, Port.typeApplication]) $ \p - do So there are some plain actions like Client.setName and Port.withSimple before it gets to the next do block. How would I write this in ContT style? You can use the lift function to lift actions from the underlying monad to the transformer. In your case it'd be something like flip runContT return $ do h - ContT $ SndSeq.withDefault SndSeq.Block lift $ Client.setName (h :: SndSeq.T SndSeq.DuplexMode) Haskell-Melody p - ContT $ Port.withSimple h out (Port.caps [Port.capRead, Port.capSubsRead, Port.capWrite]) (Port.types [Port.typeMidiGeneric, Port.typeApplication]) ... Roman ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Library API design: functional objects VS type classes
What is the advance of using type classes? A function of the form f :: Show a = ... really has an implicit argument f :: Show__Dict a - ... that the compiler infers for us. So, the advantage of type classes is one of convenience: we don't have to pass dictionaries around, or even figure out which dictionaries we need; the compiler does that for us. But if we have a type class of the form class Foo a where mkFoo :: IO FooToken otherFun1 :: FooToken - ... otherFun2 :: FooToken - ... then this advantage is mostly lost; we still need to pass around an explicit FooToken object. In a case like this, I don't see the advantage of using a type class over using a data type data Foo = Foo { otherFun1 :: ... , otherFun2 :: ... } mkFoo :: .. - Foo There are exceptions; for instance, if you want to encode 'inheritance' in some way then type classes might still be useful; for instance, see the Gtk2Hs library, which uses this extensively. Edsko ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Simple way to do something like ArrowChoice.right on a Conduit? (version 1.0.0)
Wow, I hadn't realized that someone had implemented resumable sinks... and now resumable conduits too! Very interesting. I'm not sure if I entirely understand your use case, but in general it should be possible to have multiple Conduits running one after the other. Here's an example of restarting an accumulator after every multiple of 5: https://www.fpcomplete.com/user/snoyberg/random-code-snippets/multiple-conduits Michael On Mon, Mar 4, 2013 at 6:55 PM, Joey Adams joeyadams3.14...@gmail.comwrote: On Sun, Mar 3, 2013 at 10:24 PM, Joey Adams joeyadams3.14...@gmail.comwrote: ... Here's a possible API for a resumable Conduit: newtype ResumableConduit i m o = -- hidden -- newResumableConduit :: Monad m = Conduit i m o - ResumableConduit i m o -- | Feed the 'Source' through the conduit, and send any output from the -- conduit to the 'Sink'. When the 'Sink' returns, close the 'Source', but -- leave the 'ResumableConduit' open so more data can be passed through it. runResumableConduit :: Monad m = ResumableConduit i m o - Source m i - Sink o m r - m (ResumableConduit i m o, r) ... While trying to implement this, I found a more elegant interface for resuming the ResumableConduit: -- | Fuse a 'ResumableConduit' to a 'Sink'. When the 'Sink' returns, -- it returns the 'ResumableConduit' so the caller can reuse it. (=$++) :: Monad m = ResumableConduit i m o - Sink o m r - Sink i m (ResumableConduit i m o, r) This takes advantage of Sink's return value to forward the ResumableConduit. I don't think a ($=++) can be implemented. Advantages: * (=$++) is easier to implement than 'runResumableConduit' since it only has to fuse two pipes together instead of three. * Pretty syntax: (resumable', a) - source $$ resumable =$++ sink ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Haskell + RankNTypes + (forall p. p Char - p Bool) sound?
Just because you can't use the 'magic primitive' in question to produce an element of the empty type doesn't mean the system is sound (nor does type soundness have anything to do with proving 'false'). The question is what the primitive is supposed to do. If it's supposed to work as a witness of equality between Char and Bool, then (sym prim . prim :: p Char - p Char) must be refl, the identity function. But then if we choose p = Identity, we have f :: Char - Char via round-trip through Bool that must be the identity. In a sufficiently capable language, that can be shown impossible via the pigeonhole principle, but I'm not sure if 'just rank-n types' is up to the task. Some other food for thought is that 'true = false' (true and false beeing booleans) is not sufficient to derive false in dependent type theory _unless_ there is some kind of large elimination, either directly or via universes. Without those, type theory admits trivial models in which every type denotes a set of at most one element. One can see then that it might take the ability to do case analysis on types to gain a contradiction from 'Char = Bool' in GHC (the pigeonhole route doesn't seem like it'd be feasible), although I don't know that that's the case. Anyhow, soundness is with respect to a model. In the usual model of Haskell, every domain is nonempty, including the one for p Char - p Bool. So if you don't specify anything about the primitive, it could be undefined, and there'd be no problem with type soundness. And it may also be the case that you can introduce a primitive that is not parametric in p, and arbitrarily applies functions f :: Char - Bool, g :: Bool - Char in the right places for each particular p definable in the language. That will fail the properties of an equality witness, but if you don't specify any properties at all, anything goes (and you can't really prove anything about the action of Leibniz or any other equality in GHC anyhow, so it can't contradict anything there). i don't really know the answer to whether TypeFamilies/GADTs is merely sufficient or necessary, though. On Tue, Mar 5, 2013 at 3:54 AM, Shachaf Ben-Kiki shac...@gmail.com wrote: I was trying to figure out a way to write absurd :: (forall p. p Char - p Bool) - Void using only rank-n types. Someone suggested that Haskell with RankNTypes and a magic primitive of type (forall p. p Char - p Bool) might be sound (disregarding the normal ways to get ⊥, of course). Is that true? Given either TypeFamilies or GADTs, you can write absurd. But it doesn't seem like you can write it with just RankNTypes. (This is related to GeneralizedNewtypeDeriving, which is more or less a version of that magic primitive.) This seems like something that GADTs (/TypeFamilies) give you over Leibniz equality: You can write data Foo a where FooA :: Foo Char FooB :: Void - Foo Bool foo :: Foo Bool - Void foo (FooB x) = x Without any warnings. On the other hand data Bar a = BarA (Is a Char) | BarB (Is a Bool) Void bar :: Bar Bool - Void bar (BarB _ x) = x bar (BarA w) = -- ??? Doesn't seem possible. If it's indeed impossible, what's the minimal extension you would need to add on top of RankNTypes to make it work? GADTs seems way too big. Shachaf ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Concurrency performance problem
Depends on the application, of course. The (on by default) parallel GC tends to kill performance for me... you might try running both with +RTS -sstderr to see if GC time is significantly higher, and try adding +RTS -qg1 if it is. On Mon, Mar 4, 2013 at 2:23 PM, Łukasz Dąbek sznu...@gmail.com wrote: 2013/3/4 bri...@aracnet.com: do you have a link to the new code ? Diff is at the bottom of original code: http://hpaste.org/83460. If you just pass -N, GHC automatically sets the number of threads based on the number of cores on your machine. Yes, I know that. I am just wondering why seemingly single threaded computation (look at singleThreadIntegrate in source code from first post) runs slower with increasing number of cores available (set through -N option). -- Łukasz Dąbek ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Concurrency performance problem
2013/3/5 Nathan Howell nathan.d.how...@gmail.com Depends on the application, of course. The (on by default) parallel GC tends to kill performance for me... you might try running both with +RTS -sstderr to see if GC time is significantly higher, and try adding +RTS -qg1 if it is. You are correct: parallel GC is slowing computation down. After some experiments I can produce two behaviors: use single threaded GC (multithreaded version is slowed down by factor of 5 - but single threaded backs to normal) or increase heap size (multithreaded version slows down by factor of 2, single threaded version runs normally). I guess I must live with this ;) -- Łukasz Dąbek ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] translating recursively defined sequence
On 13-03-05 12:19 AM, Christopher Howard wrote: Hi. My Haskell is (sadly) getting a bit rusty. I was wondering what would be the most straightforward and easily followed procedure for translating a recursively defined sequence into a Haskell function. For example, this one from a homework assignment. quote: a_1 = 10 a_(k+1) = (1/5) * (a_k)**2 (The underscore is meant to represent subscripting what follows it.) 1. decode subscripts back to arguments a 1 = 10 a (k+1) = (1/5) * (a k)**2 2. normalize LHS arguments sometimes, some arguments on the LHS (k+1 here) are not accepted by Haskell 2010; therefore, we need an equivalent definition with another argument form. a 1 = 10 a k = (1/5) * (a (k-1))**2 3. translate to Haskell (that's right, the above two steps are pure math, not Haskell) a 1 = 10 a k = (1/5) * (a (k-1))**2 The result may or may not be an efficient algorithm (which depends on how you use it). But it gives the correct answer. An efficient algorithm requires further study. Here is an example where step 3 makes change. b_0 = 0 b_(k+1) = sqrt k * b_k 1. decode subscripts back to arguments b 0 = 0 b (k+1) = sqrt k * b k 2. normalize LHS arguments b 0 = 0 b k = sqrt (k-1) * b (k-1) 3. translate to Haskell b 0 = 0 b k = sqrt (fromIntegral (k-1)) * b (k-1) ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] translating recursively defined sequence
Isn't that already valid Haskell? :) (remove the underscore). On Mar 5, 2013 5:21 AM, Christopher Howard christopher.how...@frigidcode.com wrote: Hi. My Haskell is (sadly) getting a bit rusty. I was wondering what would be the most straightforward and easily followed procedure for translating a recursively defined sequence into a Haskell function. For example, this one from a homework assignment. quote: a_1 = 10 a_(k+1) = (1/5) * (a_k)**2 (The underscore is meant to represent subscripting what follows it.) -- frigidcode.com ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Library API design: functional objects VS type classes
On Mon, Mar 4, 2013 at 5:50 PM, Rob Stewart robstewar...@gmail.com wrote: ... - import Control.Concurrent -- API approach 1: Using type classes class FooC a where mkFooC :: IO a readFooC :: a - IO Int incrFooC :: a - IO () I recommend taking 'mkFooC' out of the typeclass. It keeps you from being able to (easily) construct a 'FooC' from dynamic data, e.g.: mkFoo :: Host - Port - IO MyFoo After this change, the typeclass approach and the data constructor approach are nearly equivalent, except: * With the typeclass approach, the compiler passes the dictionary implicitly, which can be more convenient to use (e.g. `readFooC a` instead of `readFooC (getFoo a)`). * With the typeclass approach, you have to define a Foo type to contain the environment needed for Foo methods. With the record approach, you can just construct and use a FooT record directly. Either way, don't forget about simple encapsulation: data LineDevice -- abstract -- Some LineDevice constructors for common tasks stdio :: LineDevice openFile :: FilePath - IO LineDevice connectTo :: HostName - PortId - IO LineDevice getLine :: LineDevice - Int - IO ByteString putLine :: LineDevice - ByteString - IO () This interface is very easy to understand. If you want to let users make their own LineDevice objects, you can still provide an internal module with something like this: data Driver = Driver { getLine :: Int - IO ByteString , putLine :: ByteString - IO () } newLineDevice :: Driver - IO LineDevice Hope this helps, -Joey ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] ANNOUNCE: io-streams 1.0.0.0
Hi all, After more than eight months of careful design and development, The Snap Framework team is happy to announce the first version of io-streams, a simple and easy-to-use library for doing streaming I/O in Haskell. The io-streams library is based around two basic types, InputStream a and OutputStream a, and three fundamental I/O primitives: -- read an item from an input stream read :: InputStream a - IO (Maybe a) -- push an item back to an input stream unRead :: a - InputStream a - IO () -- write to an output stream write :: Maybe a - OutputStream a - IO () Streams can be transformed by composition and hooked together (using Kleisli composition) with a large set of provided combinators. Simple types and operations in the IO monad mean straightforward and simple exception handling and resource cleanup using Haskell standard library functions like bracket. The io-streams library comes with: - functions to use files, handles, concurrent channels, sockets, lists, vectors, and more as streams. - a plethora of combinators for wrapping and transforming streams, including compression and decompression using zlib, controlling precisely how many bytes are read from or written to a stream, buffering output using bytestring builders, folds, maps, filters, zips, etc. - support for parsing from streams using attoparsec. For first-time users, io-streams comes with an included tutorial in theSystem.IO.Streams.Tutorial module, written by Gabriel Gonzalez of “pipes” fame. The io-streams library is tested on GHC 7.0, 7.2, 7.4, and 7.6, and includes an extensive test suite with 100% function, statement, and branch coverage. We would like to acknowledge the financial assistance of Erudify AG, who graciously funded some of the documentation and development of the io-streams library. Many thanks are also due to Gabriel Gonzalez, Andrew Cowie, Johan Tibell, and Bas van Dijk for their helpful discussions, contributions, and review. For further details, you can read our release announcement here: http://snapframework.com/blog/2013/03/05/announcing-io-streams Cheers, G -- Gregory Collins g...@gregorycollins.net ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] ANNOUNCE: io-streams 1.0.0.0
Is this something like conduits ? ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Simple way to do something like ArrowChoice.right on a Conduit? (version 1.0.0)
On Tue, Mar 5, 2013 at 9:24 AM, Michael Snoyman mich...@snoyman.com wrote: ... I'm not sure if I entirely understand your use case, but in general it should be possible to have multiple Conduits running one after the other. Here's an example of restarting an accumulator after every multiple of 5: https://www.fpcomplete.com/user/snoyberg/random-code-snippets/multiple-conduits Neat. I didn't think to do that with plain Conduits. I did realize I could use a resumable conduit as a temporary filter (basically what your example does). This suggests that a resumable conduit can be used in any consumer (Conduit or Sink), not just a sink. Perhaps it can even be used in a producer, though different operators would be needed (+$= instead of =$+). In my compression example, the incoming message sink needs to feed chunks of compressed data to a zlib conduit. It can't just hand full control of the input to zlib; it has to decode messages, and only send CompressedData messages through zlib. I need a resumable conduit for that. Here's my current implementation of resumable conduits [1]. I don't know much about conduit finalizers; I mostly followed 'connectResume' and 'pipeL'. The main wrinkle is that when the ResumableConduit receives an upstream terminator, it forwards it to the sink, rather than telling the conduit that the stream ended. This allows the conduit to be reused. Only when we finish the ResumableConduit () do we send it the stream terminator. I'll continue toying with this. It might be possible to factor out terminator forwarding, and generalize connectResume to support resumable sources, conduits, and sinks. Thanks for the help, -Joey [1]: https://github.com/joeyadams/hs-resumable-conduit/blob/master/ResumableConduit.hs ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] ANNOUNCE: io-streams 1.0.0.0
s9gf4ult wrote: Is this something like conduits ? Yes, its also a bit like Iteratee, Enumerator, Pipes and Machines. Erik -- -- Erik de Castro Lopo http://www.mega-nerd.com/ ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Simple way to do something like ArrowChoice.right on a Conduit? (version 1.0.0)
On Wed, Mar 6, 2013 at 5:48 AM, Joey Adams joeyadams3.14...@gmail.comwrote: On Tue, Mar 5, 2013 at 9:24 AM, Michael Snoyman mich...@snoyman.comwrote: ... I'm not sure if I entirely understand your use case, but in general it should be possible to have multiple Conduits running one after the other. Here's an example of restarting an accumulator after every multiple of 5: https://www.fpcomplete.com/user/snoyberg/random-code-snippets/multiple-conduits Neat. I didn't think to do that with plain Conduits. I did realize I could use a resumable conduit as a temporary filter (basically what your example does). This suggests that a resumable conduit can be used in any consumer (Conduit or Sink), not just a sink. Perhaps it can even be used in a producer, though different operators would be needed (+$= instead of =$+). In my compression example, the incoming message sink needs to feed chunks of compressed data to a zlib conduit. It can't just hand full control of the input to zlib; it has to decode messages, and only send CompressedData messages through zlib. I need a resumable conduit for that. I'm still not sure I follow this. In the example I linked to, the go function within breaker could arbitrarily modify the data before it gets passed on to the inner Conduit. So it seems like it should be possible to achieve your goals this way. But I may just not fully understand your use case. Michael Here's my current implementation of resumable conduits [1]. I don't know much about conduit finalizers; I mostly followed 'connectResume' and 'pipeL'. The main wrinkle is that when the ResumableConduit receives an upstream terminator, it forwards it to the sink, rather than telling the conduit that the stream ended. This allows the conduit to be reused. Only when we finish the ResumableConduit () do we send it the stream terminator. I'll continue toying with this. It might be possible to factor out terminator forwarding, and generalize connectResume to support resumable sources, conduits, and sinks. Thanks for the help, -Joey [1]: https://github.com/joeyadams/hs-resumable-conduit/blob/master/ResumableConduit.hs ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe