Re: [Haskell-cafe] simple parsec question

2013-03-05 Thread Immanuel Normann
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?

2013-03-05 Thread Shachaf Ben-Kiki
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

2013-03-05 Thread Alfredo Di Napoli
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

2013-03-05 Thread S. Doaitse Swierstra
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

2013-03-05 Thread Atsuro Hoshino
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

2013-03-05 Thread Roman Cheplyaka
* 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

2013-03-05 Thread Edsko de Vries
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)

2013-03-05 Thread Michael Snoyman
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?

2013-03-05 Thread Dan Doel
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

2013-03-05 Thread Nathan Howell
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-03-05 Thread Łukasz Dąbek
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

2013-03-05 Thread Albert Y. C. Lai

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

2013-03-05 Thread Don Stewart
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

2013-03-05 Thread Joey Adams
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

2013-03-05 Thread Gregory Collins
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

2013-03-05 Thread s9gf4ult
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)

2013-03-05 Thread Joey Adams
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

2013-03-05 Thread Erik de Castro Lopo
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)

2013-03-05 Thread Michael Snoyman
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