Re: [Haskell-cafe] Using lenses

2013-10-03 Thread Nicolas Trangez
Simon,

On Thu, 2013-10-03 at 08:07 +, Simon Peyton-Jones wrote:
 If you are using the lens library yourself, could you spare a few
minutes to tell me how you are using it?

I'm not a heavy 'lens'-user (yet), and this might not be the most pretty
use-case from a theoretic point of view, but anyway:

I use 'lens' in Kontiki [1], my implementation of Raft [2], a fairly
recent consensus protocol for distributed systems (think Paxos 
multi-Paxos, Zookeeper,...). The Raft protocol description is fairly
imperative (When in state S, if you receive a message M, broadcast
message M'(M) to all other nodes, append entry E(M) to your log, and
update the state to S'(S)), so in order to keep the code close to this
description, I created a TransitionT monad transformer (where the
underlying monad should, in some cases, provide access to the persisted
log of the system, most likely requiring IO access, but this is
abstracted over), which is basically RWST.

The R environment gives access to system configuration (e.g. the set of
nodes (or at least their names/IDs) part of the cluster), W is used to
output/list Commands to be executed as part of a state transition, S
gives access to the current state, and a transition should yield a new
state (or the old one if e.g. a message is received which should be
ignored in the current state). See [3] for an overview of the types
involved.

Finally, after this long introduction, the 'lens' part: thanks to the
'lens' operators, and my types involved in the TransitionT monad
(specifically the R environment and S state) being lens'ified, accessing
R  S becomes fairly unobtrusive and more imperative-looking (which
makes sense when using RWS). As an example, in [4], you see some parts
of the current (Candidate) state being accessed:

currentTerm - use cCurrentTerm
votes - use cVotes

Not using 'lens', this would be something (OTOH) like

currentTerm - fmap _cCurrentTerm get

which is less familiar from an imperative POV.

Then also updating the current state 'in-place' (not for real,
obviously):

cVotes %= Set.insert sender

And accessing the configuration (R) environment, e.g.:

nodeId - view configNodeId

See other handler functions in that module, or in the Follower and
Leader modules in the same directory, for more examples.

Regards,

Nicolas

[1] https://github.com/NicolasT/kontiki
[2]
https://ramcloud.stanford.edu/wiki/download/attachments/11370504/raft.pdf
[3]
https://github.com/NicolasT/kontiki/blob/master/src/Network/Kontiki/Types.hs
[4]
https://github.com/NicolasT/kontiki/blob/master/src/Network/Kontiki/Raft/Candidate.hs#L32

___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Proposal: Partitionable goes somewhere + containers instances

2013-09-29 Thread Nicolas Trangez
I'd think

partition :: t - Either t (t, t)

might be more suited then...

Nicolas
On Sep 29, 2013 1:21 AM, Ryan Newton rrnew...@gmail.com wrote:

 subject change

 On Sun, Sep 29, 2013 at 3:31 AM, Mike Izbicki m...@izbicki.me wrote:

 I've got a Partitionable class that I've been using for this purpose:

 https://github.com/mikeizbicki/ConstraintKinds/blob/master/src/Control/ConstraintKinds/Partitionable.hs


 Mike -- Neat, that's a cool library!

 Edward --  ideally, where in the standard libraries should the
 Partitionable comonoid go?

 Btw, I'm not sure what the ideal return type for comappend is, given that
 it needs to be able to bottom out.  Mike, our partition function's list
 return type seems more reasonable.  Or maybe something simple would be this:

 *class Partitionable t where*
 *  partition :: t - Maybe (t,t)*

 That is, at some point its not worth splitting and returns Nothing, and
 you'd better be able to deal with the 't' directly.

 So what I really want is for the *containers package to please get some
 kind of Partitionable instances! * Johan  others, I would be happy to
 provide a patch if the class can be agreed on. This is important because
 currently the balanced tree structure of Data.Set/Map is an *amazing and
 beneficial property* that is *not* exposed at all through the API.
For example, it would be great to have a parallel traverse_ for Maps
 and Sets in the Par monad.  The particular impetus is that our new and
 enhanced Par monad makes extensive use of Maps and Sets, both the pure,
 balanced ones, and lockfree/inplace ones based on concurrent skip lists:

 http://www.cs.indiana.edu/~rrnewton/haddock/lvish/

 Alternatively, it would be ok if there were a Data.Map.Internal module
 that exposed the Bin/Tip, but I assume people would rather have a clean
 Partitionable instance...

 Best,
   -Ryan


 On Sun, Sep 29, 2013 at 3:31 AM, Mike Izbicki m...@izbicki.me wrote:

 I've got a Partitionable class that I've been using for this purpose:


 https://github.com/mikeizbicki/ConstraintKinds/blob/master/src/Control/ConstraintKinds/Partitionable.hs

 The function called parallel in the HLearn library will automatically
 parallelize any homomorphism from a Partionable to a Monoid.  I
 specifically use that to parallelize machine learning algorithms.

 I have two thoughts for better abstractions:

 1)  This Partitionable class is essentially a comonoid.  By reversing the
 arrows of mappend, we get:

 comappend :: a - (a,a)

 By itself, this works well if the number of processors you have is a
 power of two, but it needs some more fanciness to get things balanced
 properly for other numbers of processors.  I bet there's another algebraic
 structure that would capture these other cases, but I'm not sure what it is.

 2) I'm working with parallelizing tree structures right now (kd-trees,
 cover trees, oct-trees, etc.).  The real problem is not splitting the
 number of data points equally (this is easy), but splitting the amount of
 work equally.  Some points take longer to process than others, and this
 cannot be determined in advance.  Therefore, an equal split of the data
 points can result in one processor getting 25% of the work load, and the
 second processor getting 75%.  Some sort of lazy Partitionable class that
 was aware of processor loads and didn't split data points until they were
 needed would be ideal for this scenario.

 On Sat, Sep 28, 2013 at 6:46 PM, adam vogt vogt.a...@gmail.com wrote:

 On Sat, Sep 28, 2013 at 1:09 PM, Ryan Newton rrnew...@gmail.com wrote:
  Hi all,
 
  We all know and love Data.Foldable and are familiar with left folds and
  right folds.  But what you want in a parallel program is a balanced
 fold
  over a tree.  Fortunately, many of our datatypes (Sets, Maps) actually
 ARE
  balanced trees.  Hmm, but how do we expose that?

 Hi Ryan,

 At least for Data.Map, the Foldable instance seems to have a
 reasonably balanced fold called fold (or foldMap):

   fold t = go t
 where   go (Bin _ _ v l r) = go l `mappend` (v `mappend` go r)

 This doesn't seem to be guaranteed though. For example ghc's derived
 instance writes the foldr only, so fold would be right-associated for
 a:

  data T a = B (T a) (T a) | L a deriving (Foldable)

 Regards,
 Adam
 ___
 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


___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Bytestring map/zipWith rationale

2013-09-12 Thread Nicolas Trangez
I did use that a couple of times (`xor`ing 2 ByteStrings together), and was
surprised by the omission back then, but IIRC (can't validate now), there's
a specialised zipWith (as proposed) in the module (with some other name,
obviously), which is not exported, but used when you 'pack' the result of
'zipWith' when the result is '[Word8]'... You might want to look into that.

Nicolas
On Sep 12, 2013 8:11 PM, John Lato jwl...@gmail.com wrote:

 Carter: we don't have both.  We have one function from each category.  My
 guess is nobody's ever really needed a really fast zipWith ::
 (Word8-Word8-Word8) - ByteString - ByteString - ByteString; that's the
 only reason I can think of for its omission.


 On Thu, Sep 12, 2013 at 10:45 AM, Carter Schonwald 
 carter.schonw...@gmail.com wrote:

 Scott: benchmark the two and you'll see why we have both :-)


 On Thursday, September 12, 2013, Scott Lawrence wrote:

 On Thu, 12 Sep 2013, Tom Ellis wrote:

  On Thu, Sep 12, 2013 at 09:21:20AM -0400, Scott Lawrence wrote:

 Something's always bothered me about map and zipWith for ByteString.
 Why is it

 map :: (Word8 - Word8) - ByteString - ByteString

 but

 zipWith :: (Word8 - Word8 - a) - ByteString - ByteString - [a]


 Well, what if you wanted to zipWith a function of type Word8 - Word8
 -
 Foo instead of Word8 - Word8 - Word8?


 Then I would do what I do with map, and call `unpack` first.

 Either of the two options is usable:

  map :: (Word8 - Word8) - ByteString - ByteString
  zipWith :: (Word8 - Word8 - Word8) - ByteString - ByteString -
 ByteString
(or)
  map :: (Word8 - a) - ByteString - [a]
  zipWith :: (Word8 - Word8 - a) - ByteString - ByteString - [a]

 I just don't understand why we have one from each.

 --
 Scott Lawrence
 __**_
 Haskell-Cafe mailing list
 Haskell-Cafe@haskell.org
 http://www.haskell.org/**mailman/listinfo/haskell-cafehttp://www.haskell.org/mailman/listinfo/haskell-cafe


 ___
 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


___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


[Haskell-cafe] Traversals of monomorphic containers (was: Re: mapM_ for bytestring)

2013-09-02 Thread Nicolas Trangez
# Redirected to haskell-cafe

On Sun, 2013-09-01 at 14:58 +0400, Artyom Kazak wrote:
 Would this be an appropriate place to propose adding mapM_ (and then  
 possibly mapM) to bytestring library?
 
 Was it suggested before? If yes, why was it rejected?

This got me wondering: there are several type-classes useful for
polymorphic container types, e.g. Functor, Foldable  Traversable which
all apply to some type of kind (* - *).

Are there related things for monomorphic containers, like ByteString,
Text or some newtype'd Vector with fixed element type, e.g.

class MFunctor f a where
mfmap :: (a - a) - f - f

instance MFunctor ByteString Word8 where
mfmap = ByteString.map

or (maybe even better)

class MFunctor f where
type Elem
mfmap :: (Elem - Elem) - f - f

instance MFunctor ByteString where
type Elem = Word8
mfmap = ByteString.map

and similar for other classes.

Nicolas


___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Proposal: Generic conditions for 'if' and 'case'

2013-09-02 Thread Nicolas Trangez
On Sun, 2013-09-01 at 15:51 -0700, Wvv wrote:
 I think it is an old idea, but nevertheless.
 Now we have next functions:
 
 if (a :: Bool) then x else y
 
 case b of
 a1 :: Bool - x1
 a2 :: Bool - x2
 ...
 
 Let we have generic conditions for 'if' and 'case':
 
 class Boolean a where
 toBool :: a - Bool
 
 instance Boolean Bool where
toBool = id
 
 instance Boolean [a] where
toBool [] = False
toBool _ = True
 
 instance Boolean (Maybe a) where
toBool Nothing = False
toBool _ = True
 
 instance Boolean Int where
toBool 0 = False
toBool _ = True
 
 if' (a :: Boolean b) then x else y
 
 case' d of
 a1 :: Boolean b1 - x1
 a2 :: Boolean b2 - x2
 ...
 
 
 It is very easy to implement to desugar:
 if' a then ... == if toBool ( a ) then ...

I wasn't at my computer when I sent my previous reply, so here's a more
full-fledged answer:

This is possible using the RebindableSyntax extension. Make sure to read
the documentation of the extension before using it, it might have some
unexpected implications.

Be careful when using this scheme as well... I'd think lots of
Haskell'ers would frown upon this kind of implicit conversions (they
remind me of Python and its __nonzero__ stuff).

Here's an example implementing your proposal:

{-# LANGUAGE RebindableSyntax #-}

import Prelude

class Boolean a where
toBool :: a - Bool

instance Boolean Bool where
toBool = id

instance Boolean [a] where
toBool = not . null

instance Boolean (Maybe a) where
toBool = maybe False (const True)

instance Boolean Int where
toBool = (/= 0)

ifThenElse :: Boolean a = a - b - b - b
ifThenElse i t e = case toBool i of
True - t
False - e

main :: IO ()
main = do
test False
test ([] :: [Int])
test [1]
test (Nothing :: Maybe Int)
test (Just 1 :: Maybe Int)
test (0 :: Int)
test (1 :: Int)
{- test 'c' fails to type-check: no instance Boolean Char defined!
-}
  where
test v = putStrLn $ show v ++  is  ++ (if v then true else
false)

which outputs

False is false
[] is false
[1] is true
Nothing is false
Just 1 is true
0 is false
1 is true

Using RebindableSyntax, 'if I then T else E' is rewritten into
'ifThenElse I T E' by the compiler, for whatever 'ifThenElse' is in
scope.

Nicolas


___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Proposal: Generic conditions for 'if' and 'case'

2013-09-01 Thread Nicolas Trangez
I didn't test it, but you might want to look into the 'rebindable syntax'
extension and its 'ifThenElse' feature.

Nicolas
On Sep 2, 2013 12:51 AM, Wvv vite...@rambler.ru wrote:

 I think it is an old idea, but nevertheless.
 Now we have next functions:

 if (a :: Bool) then x else y

 case b of
 a1 :: Bool - x1
 a2 :: Bool - x2
 ...

 Let we have generic conditions for 'if' and 'case':

 class Boolean a where
 toBool :: a - Bool

 instance Boolean Bool where
toBool = id

 instance Boolean [a] where
toBool [] = False
toBool _ = True

 instance Boolean (Maybe a) where
toBool Nothing = False
toBool _ = True

 instance Boolean Int where
toBool 0 = False
toBool _ = True

 if' (a :: Boolean b) then x else y

 case' d of
 a1 :: Boolean b1 - x1
 a2 :: Boolean b2 - x2
 ...


 It is very easy to implement to desugar:
 if' a then ... == if toBool ( a ) then ...



 --
 View this message in context:
 http://haskell.1045720.n5.nabble.com/Proposal-Generic-conditions-for-if-and-case-tp5735366.html
 Sent from the Haskell - Haskell-Cafe mailing list archive at Nabble.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


[Haskell-cafe] TypeLits Typeable

2013-08-24 Thread Nicolas Trangez
Hello Cafe,

I was playing around with TypeLits in combination with Typeable (using
GHC 7.7.7.20130812 FWIW), but was surprised to find Symbols aren't
Typeable, and as such the following doesn't work. Is this intentional,
or am I missing something?

Thanks,

Nicolas

{-# LANGUAGE DataKinds,
 KindSignatures,
 DeriveFunctor,
 DeriveDataTypeable #-}
module Main where

import Data.Typeable
import GHC.TypeLits

data NoSymbol n a b = NoSymbol a b
  deriving (Typeable)

data WithSymbol (n :: Symbol) a b = WithSymbol a b
  deriving (Typeable)

data Sym
  deriving (Typeable)

main :: IO ()
main = do
print $ typeOf (undefined :: NoSymbol Sym Int Int)

let d = undefined :: WithSymbol sym Int Int
{-
print $ typeOf d

No instance for (Typeable Symbol sym)
  arising from a use of ‛typeOf’
-}

return ()


___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Yet Another Forkable Class

2013-08-23 Thread Nicolas Trangez
On Fri, 2013-08-23 at 08:06 +, o...@okmij.org wrote:
  It will
  arbitrarily pick the first match in the former and fail to compile
 in
  the latter case.
 Of course we can have duplicate layers. In that case, the dynamically
 closest
 handler wins -- which sounds about right (think of reset in delimited
 control).

Did anyone ever consider using type-level literals (strings) to 'name'
effects (or transformer layers when using monad stacks)?

A stupid example (OTOH) could be

updateStats :: (Member (State min Int) r, Member (State max Int)
r) = Int - Eff r ()
updateStats i = do
min - askMin
max - askMax
when (i  min) $ putMin i
when (i  max) $ putMax i
  where
askMin :: Member (State min Int) r = Eff r Int
askMin = ask
putMax :: Member (State max Int) r = Int - Eff r ()
putMax = put
-- askMax, putMin accordingly

Using constraint synonyms/ConstraintKinds (e.g. type StateMax r = Member
(State max Int) r) might reduce some notation overhead.

Just a thought.

Nicolas


___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


[Haskell-cafe] Stuck on design problem

2013-05-20 Thread Nicolas Trangez
All,

Since I'm stuck on a coding problem and can't figure out how to proceed,
I decided to call for help.

I'm unable to get some code to typecheck, so maybe I'm missing something
obvious on the implementation side, or more likely the design is
completely wrong.

Here's the idea: I have some code which uses some log of Entry a
values (for some polymorphic type 'a'), and provides actions which
output Command a values which should be interpreted by some wrapper
code, e.g. adding some new entries to the log. These actions are
implemented in a custom WriterT transformer (in this demo code, the
original is more complex) to output Commands, while the inner monad
should give access to the log entries (this could be in-memory like in
the example, or stored on disk so using IO).

You can find a trimmed-down version at
https://gist.github.com/NicolasT/4230251f4f87f110d197

This doesn't type-check, and I'm not sure how to proceed. Am I taking a
wrong approach? Do I need a different design?

Thanks,

Nicolas


___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


[Haskell-cafe] Failure deriving MonadRWS when using a type-family for the State part

2013-05-20 Thread Nicolas Trangez
All,

The following code results in a compilation error (I tried GHC 7.4.1  a
7.7.20130430 build):

{-# LANGUAGE TypeFamilies,
 GeneralizedNewtypeDeriving,
 StandaloneDeriving #-}

module Main where

import Control.Applicative
import Control.Monad.RWS

data C = C
data E = E

data S1 = S1 Int

type family I a :: *
type instance I S1 = Int

newtype T a s m r = T { unT :: RWST C [E] (I s) m r }
  deriving ( Functor
   , Applicative
   , Monad
   , MonadReader C
   , MonadWriter [E]
   , MonadState (I s)
   , MonadRWS C [E] (I s)
   , MonadTrans
   )

Error:

No instance for (MonadState (I s) (T a s m))
  arising from the 'deriving' clause of a data type declaration
Possible fix:
  use a standalone 'deriving instance' declaration,
so you can specify the instance context yourself
When deriving the instance for (MonadRWS C [E] (I s) (T a s m))

Commenting out the MonadRWS line from the derivings list (i.e. the line
pointed at by the error) works as expected. I was somehow unable to get
a suitable standalone-deriving clause working, so didn't test that.

Is this expected?

Regards,

Nicolas


___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Stuck on design problem

2013-05-20 Thread Nicolas Trangez
Miguel,

On Mon, 2013-05-20 at 16:38 +0400, Miguel Mitrofanov wrote:
 :t runMemLog (runTransitionT $ demo 1)
 runMemLog (runTransitionT $ demo 1)
   :: MonadLog (MemLog a) () = Log a - ((), [Command ()])
 
 That means, that foo, if you manage to compile it, would have type MonadLog 
 (MemLog a) () = ((), [Command ()]). That means that in each call for foo it 
 would be used as something of the type ((), [Command ()]), therefore giving 
 no indication of which a should be used. The fact that there is only one 
 instance of MonadLog (MemLog a) () - namely, the one with a = () - doesn't 
 matter, as there could be others in the future. That's why GHC is complaining.
 
 So, you have to provide such indication by youself, replacing IntMap.empty 
 with (IntMap.empty :: Log ()).

Thanks for the pointer. I tried using an explicit type-annotation myself
before as well, but that failed, and I found the root-cause: in my
original code, the type-signature of runTransitionT was all wrong,
instead of

  runTransitionT :: TransitionT a m a - m (a, [Command a])

this was intended to be

  runTransitionT :: TransitionT a m r - m (r, [Command a])

After making this change, and using an explicit type-signature for the
empty IntMap as you suggested, things work as expected, see
https://gist.github.com/NicolasT/4230251f4f87f110d197/revisions

In my original code, this didn't help out somehow (some other things at
play there as well), but another suggestion on this list did.

Thanks for the help!

Nicolas


 
 20.05.2013, 15:36, Nicolas Trangez nico...@incubaid.com:
  All,
 
  Since I'm stuck on a coding problem and can't figure out how to proceed,
  I decided to call for help.
 
  I'm unable to get some code to typecheck, so maybe I'm missing something
  obvious on the implementation side, or more likely the design is
  completely wrong.
 
  Here's the idea: I have some code which uses some log of Entry a
  values (for some polymorphic type 'a'), and provides actions which
  output Command a values which should be interpreted by some wrapper
  code, e.g. adding some new entries to the log. These actions are
  implemented in a custom WriterT transformer (in this demo code, the
  original is more complex) to output Commands, while the inner monad
  should give access to the log entries (this could be in-memory like in
  the example, or stored on disk so using IO).
 
  You can find a trimmed-down version at
  https://gist.github.com/NicolasT/4230251f4f87f110d197
 
  This doesn't type-check, and I'm not sure how to proceed. Am I taking a
  wrong approach? Do I need a different design?
 
  Thanks,
 
  Nicolas
 
  ___
  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] Stuck on design problem

2013-05-20 Thread Nicolas Trangez
Adam,

On Mon, 2013-05-20 at 13:37 +0100, Adam Gundry wrote:
 Hi Nicolas,
 
 Your design doesn't look too unreasonable, though I haven't looked at in
 detail. I do have a quick observation regarding the implementation that
 I hope might help. Your gist defines
 
  class MonadLog m a where
getEntry :: Index - m (Entry a)
 
  instance MonadLog (MemLog a) a
 
 and then you hit the error
 
  No instance for (MonadLog (MemLog a0) ())
 
 which is a tell-tale ambiguity problem. This is a common issue with
 multi-parameter type classes. GHC cannot determine the existential
 variable a0, because it will not commit to the instance for MemLog in
 case a more specific instance turns up.
 
 One option is to turn on GADTs or TypeFamilies and write
 
  instance a ~ a' = MonadLog (MemLog a) a'
 
 which will allow the instance to match and generate the easily solved
 constraint a0 ~ (). You may need to do the same for other instances.
 
 Alternatively, you could add a functional dependency
 
  class MonadLog m a | m - a
 
 or use a type family:
 
  class MonadLog' m where
type Element m
getEntry' :: Index - m (Entry (Element m))
 
  instance MonadLog' (MemLog a) where
type Element (MemLog a) = a
getEntry' i = flip (IntMap.!) i `fmap` ask
 

Thanks a bunch. Using FunDeps, things work as expected, also in my more
complicated original code. I chose the FunDeps approach because it seems
the least intrusive (no need to clutter instances).

Thanks a bunch for all help, this list is certainly one of the things
which makes writing Haskell code a very rewarding experience.

Thanks,

Nicolas


___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Failure deriving MonadRWS when using a type-family for the State part

2013-05-20 Thread Nicolas Trangez
The mistake might be on my side, since I expected the following to work
(but it doesn't, most likely for good reason, I didn't read any
TypeFamilies papers yet):

{-# LANGUAGE GeneralizedNewtypeDeriving, TypeFamilies #-}

module Main where

import Control.Monad.State

data S = S T
data T = T

type family F s :: *
type instance F S = T

newtype MT s m r = MT { unMT :: StateT (F s) m r }
  deriving (Monad, MonadState (F s))

-- foo :: Monad m = MT S m T
-- foo = get

{-

Could not deduce (MonadState T (MT S m))
  arising from a use of `get'
from the context (Monad m)
  bound by the type signature for foo :: Monad m = MT S m T
  at tf2.hs:17:1-9
Possible fix:
  add (MonadState T (MT S m)) to the context of
the type signature for foo :: Monad m = MT S m T
  or add an instance declaration for (MonadState T (MT S m))
In the expression: get
In an equation for `foo': foo = get

while GHCi says, as expected:

λ :i MT
newtype MT s m r = MT {unMT :: StateT (F s) m r}
-- Defined at tf2.hs:13:9
instance Monad m = Monad (MT s m) -- Defined at tf2.hs:14:13
instance Monad m = MonadState (F s) (MT s m)
  -- Defined at tf2.hs:14:20

and

λ :t undefined :: F S
undefined :: F S :: T

 -}

Nicolas

On Tue, 2013-05-21 at 00:08 +0200, Nicolas Trangez wrote:
 All,
 
 The following code results in a compilation error (I tried GHC 7.4.1  a
 7.7.20130430 build):
 
 {-# LANGUAGE TypeFamilies,
  GeneralizedNewtypeDeriving,
  StandaloneDeriving #-}
 
 module Main where
 
 import Control.Applicative
 import Control.Monad.RWS
 
 data C = C
 data E = E
 
 data S1 = S1 Int
 
 type family I a :: *
 type instance I S1 = Int
 
 newtype T a s m r = T { unT :: RWST C [E] (I s) m r }
   deriving ( Functor
, Applicative
, Monad
, MonadReader C
, MonadWriter [E]
, MonadState (I s)
, MonadRWS C [E] (I s)
, MonadTrans
)
 
 Error:
 
 No instance for (MonadState (I s) (T a s m))
   arising from the 'deriving' clause of a data type declaration
 Possible fix:
   use a standalone 'deriving instance' declaration,
 so you can specify the instance context yourself
 When deriving the instance for (MonadRWS C [E] (I s) (T a s m))
 
 Commenting out the MonadRWS line from the derivings list (i.e. the line
 pointed at by the error) works as expected. I was somehow unable to get
 a suitable standalone-deriving clause working, so didn't test that.
 
 Is this expected?
 
 Regards,
 
 Nicolas



___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Backward compatibility

2013-05-03 Thread Nicolas Trangez
On Fri, 2013-05-03 at 10:40 -0700, Hilco Wijbenga wrote:
 On 3 May 2013 09:44, Niklas Hambüchen m...@nh2.me wrote:
  While I certainly enjoy the discussion, how about addressing one of the
  original problems:
 
  On 02/05/13 13:27, Adrian May wrote:
  I just tried to use Flippi. It broke because of the syntax change so I
  tried WASH. I couldn't even install it because of the syntax change.
 
  I just fixed that in https://github.com/nh2/flippi (note that I have
  never seen this code before nor even known about it).
 
  https://github.com/nh2/flippi/commit/5e2fa93f82b4123d0d5b486209c3b722c4c1313d
 
  Had to delete 5 imports and convert one time value.
 
  Took me around 3 minutes.
 
 It seems fair to say that Haskell's designers lean more to evolution
 than maintaining backward compatibility. This reminds me of Go (the
 programming language). The approach chosen by Go's designers was to
 create a tool (gofix) that would automatically fix one's code to
 comply with the latest standard. See
 [http://talks.golang.org/2012/splash.article#TOC_17.] (yes, include
 that last period).
 
 Given the apparent simplicity of the changes needed to keep one's
 Haskell code up to snuff and the strong typing inherent in Haskell
 code, would it not be possible to create something similar? If there
 is a tool that moves (most of) one's code from Haskell version n to
 n+1 then making breaking changes would be even less of an issue.
 
 Just an idea, I have no clue about its feasibility...

I mentioned the same on #haskell today. Something like Coccinelle
(http://coccinelle.lip6.fr) semantic patches could be really useful to
automate (some) API  language changes. Somewhat like (but better than)
the Python '2to3' tool.

I think some message about a GSoC project regarding an AST-based
refactoring tool was posted to this list. That might be a useful
building block for such tool?

Imagine one day whenever a new HP release is made, GitHub pull-requests
are created automatically based on a automatically-generated patch
verified through a compilationtest-cycle on TravisCI for GH-hosted
packages published on Hackage.

Nicolas


___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] [extension]syntactic sugar for maps

2013-03-27 Thread Nicolas Trangez
On Wed, 2013-03-27 at 21:30 +0200, Răzvan Rotaru wrote:
 I am terribly missing some syntactic sugar for maps (associative data
 structures) in Haskell. I find myself using them more than any other
 data
 structure, and I think there is no big deal in adding some sugar for
 this
 to the language. I could not find out whether such an extension is
 beeing
 discussed. If not, I would like to propose and extension. Any help and
 suggestions are very welcome here. Thanks.

http://hackage.haskell.org/trac/ghc/wiki/OverloadedLists comes to mind.

Nicolas


___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Streaming bytes and performance

2013-03-19 Thread Nicolas Trangez
On Tue, 2013-03-19 at 20:32 +, Don Stewart wrote:
 Oh, I forgot the technique of inlining the lazy bytestring chunks, and
 processing each chunk seperately.
 
 $ time ./fast
 4166680
 ./fast  1.25s user 0.07s system 99% cpu 1.325 total
 
 Essentially inline Lazy.foldlChunks and specializes is (the inliner should
 really get that).
 And now we have a nice unboxed inner loop, which llvm might spot:
 
 $ ghc -O2 -funbox-strict-fields fast.hs  --make -fllvm
 $ time ./fast
 4166680
 ./fast  1.07s user 0.06s system 98% cpu *1.146 total*
 
 So about 8x faster. Waiting for some non-lazy bytestring benchmarks... :)

You could try something like this using Conduit:

{-# LANGUAGE BangPatterns #-}
module Main (main) where

import Data.Conduit
import qualified Data.Conduit.List as L
import qualified Data.Conduit.Binary as B
import qualified Data.ByteString.Char8 as BS8

main :: IO ()
main = print = runResourceT (
B.sourceFile filename $$ L.fold (\(!a) (!b) - a + BS8.count ' ' b)
(0 :: Int))
  where
filename = ...

Nicolas

 
 {-# LANGUAGE BangPatterns #-}
 
 import Data.ByteString.Internal
 import Data.ByteString.Unsafe
 import qualified Data.ByteString.Char8  as S
 import qualified Data.ByteString.Lazy.Char8 as L
 import qualified Data.ByteString.Lazy.Internal as L
 import System.IO.Posix.MMap.Lazy
 
 main = do
 f - unsafeMMapFile test.txt
 print . new 0 $ L.toChunks f
 
 new :: Int - [ByteString] - Int
 new i [] = i
 new i (x:xs) = new (add i x) xs
 
 -- jump into the fast path
 {-# INLINE add #-}
 add :: Int - ByteString - Int
 add !i !s | S.null s   = i
   | isSpace' x = add (i+1) xs
   | otherwise  = add i xs
   where T x xs = uncons s
 
 data T = T !Char ByteString
 
 uncons s = T (w2c (unsafeHead s)) (unsafeTail s)
 
 isSpace' c = c == '\n'|| c == ' '
 {-# INLINE isSpace' #-}
 
 
 
 
 On Tue, Mar 19, 2013 at 7:36 PM, Don Stewart don...@gmail.com wrote:
 
  Just for fun. Here's some improvements. about 6x faster.
  I'd be interested to see what io-streams could do on this.
 
  Using a 250M test file.
 
  -- strict state monad and bang patterns on the uncons and accumulator
  argument:
 
  $ time ./A
  4166680
  ./A  8.42s user 0.57s system 99% cpu 9.037 total
 
  -- just write a loop
 
  $ time ./A
  4166680
  ./A  3.84s user 0.26s system 99% cpu 4.121 total
 
  -- switch to Int
 
  $ time ./A
  4166680
  ./A  1.89s user 0.23s system 99% cpu 2.134 total
 
  -- custom isSpace function
 
  $ time ./A
  4166680
  ./A  1.56s user 0.24s system 99% cpu 1.808 total
 
  -- mmap IO
 
  $ time ./A
  4166680
  ./A  1.54s user 0.09s system 99% cpu 1.636 total
 
  Here's the final program:
 
 
  {-# LANGUAGE BangPatterns #-}
 
  import qualified Data.ByteStringas S
  import qualified Data.ByteString.Lazy.Char8 as L
  import System.IO.Posix.MMap.Lazy
 
  main = do
  f - unsafeMMapFile test.txt
  print $ go 0 f
where
  go :: Int - L.ByteString - Int
  go !a !s = case L.uncons s of
  Nothing - a
  Just (x,xs) | isSpaceChar8 x - go (a+1) xs
  | otherwise  - go a xs
 
  isSpaceChar8 c = c == '\n'|| c == ' '
  {-# INLINE isSpaceChar8 #-}
 
 
  On Mon, Mar 18, 2013 at 8:53 AM, Konstantin Litvinenko 
  to.darkan...@gmail.com wrote:
 
  Hi All!
 
  I tune my toy project for performance and hit the wall on simple, in
  imperative world, task. Here is the code that model what I'm trying to
  achieve
 
  import qualified Data.ByteString.Lazy as L
  import Data.Word8(isSpace)
  import Data.Word
  import Control.Monad.State
 
  type Stream = State L.ByteString
 
  get_byte :: Stream (Maybe Word8)
  get_byte = do
  s - get
  case L.uncons s of
  Nothing - return Nothing
  Just (x, xs) - put xs  return (Just x)
 
  main = do
  f - L.readFile test.txt
  let r = evalState count_spaces f
  print r
where
  count_spaces = go 0
where
  go a = do
  x - get_byte
  case x of
  Just x' -  if isSpace x' then go (a + 1) else go a
  Nothing - return a
 
  It takes the file and count spaces, in imperative way, consuming bytes
  one by one. The problem is: How to rewrite this to get rid of constant
  allocation of state but still working with stream of bytes? I can rewrite
  this as one-liner L.foldl, but that doesn't help me in any way to optimize
  my toy project where all algorithms build upon consuming stream of bytes.
 
  PS. My main lang is C++ over 10 years and I only learn Haskell :)
 
 
  __**_
  Haskell-Cafe mailing list
  Haskell-Cafe@haskell.org
  http://www.haskell.org/**mailman/listinfo/haskell-cafehttp://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] The state of binary (de)serialization

2013-02-28 Thread Nicolas Trangez
On Thu, 2013-02-28 at 01:22 -0800, wren ng thornton wrote:
 On 2/27/13 2:17 AM, Vincent Hanquez wrote:
  Two major problems of lazy bytestrings is that:
 
  * you can't pass it to a C bindings easily.
  * doing IO with it without rewriting the chunks, can sometimes (depending
 how the lazy bytestring has been produced) result in a serious
 degradation of
 performance calling syscalls on arbitrary and small chunks (e.g.
 socket's 'send').
 
 If you're on a POSIX system, you can always make use of
 unix-bytestring[1]. In particular, for lazy ByteStrings the function you
 want is System.Posix.IO.ByteString.Lazy.fdWritev which performs a single
 syscall to write all the chunks, and without manually concatenating them.
 
 [1] http://hackage.haskell.org/package/unix-bytestring

FWIW: since I saw Network.Socket.ByteString.Lazy while browsing the
'network' docs I used it ('sendAll'), and when strace'ing my demo-app (a
bad habit of mine) to my pleasant surprise (although it shouldn't have
been much of a surprise given the high-quality of Haskell unix IO
libraries) I noticed it was using writev for the bytestring chunks.

So using plain 'network' (at least the version I'm using, don't know
when this was introduced) should be sufficient to get efficient LBS
socket IO handling.

Nicolas



___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] The state of binary (de)serialization

2013-02-28 Thread Nicolas Trangez
On Mon, 2013-02-25 at 11:59 -0800, Johan Tibell wrote:
 On Mon, Feb 25, 2013 at 4:30 AM, Nicolas Trangez nico...@incubaid.comwrote:
 
  - cereal supports chunk-based 'partial' parsing (runGetPartial). It
  looks like support for this is introduced in recent versions of 'binary'
  as well (runGetIncremental)
 
 
 Yes. Binary now support an incremental interface. We intend to make sure
 binary has all the same functionality as cereal. We'd like to move away
 from having two packages if possible and since binary has the larger
 installed user base we're trying to make that the go-to package.

This will certainly make things more obvious (and maybe ready for HP
inclusion?).

  - cereal can output a strict bytestring (runPut) or a lazy one
  (runPutLazy), whilst binary only outputs lazy ones (runPut)
 
 
 The lazy one is more general and you can use toStrict (from bytestring) to
 get a strict ByteString from a lazy one, without loss of performance.

Sure. Turned out I was using lazy bs' anyway so switched to 'binary' for
deserialization.

  - Next to binary and cereal, there's bytestring's Builder interface for
  serialization, and Simon Meier's blaze-binary prototype
 
 
 Simon's builder (originally developed in blaze-binary) has been merged into
 the bytestring package. In the future binary will just re-export that
 builder.

I was referring to https://github.com/meiersi/blaze-binary

  Overall: what's the advised future-proof strategy of handling binary
  (de)serialization?
 
 
 Use binary or the builder from bytestring whenever you can. Since the
 builder in bytestring was recently added you might have to fall back to
 blaze-builder if you believe your users can't rely on the latest version of
 bytestring.

I switched to Builder for serialization. It seems to create 'more
strict' lazy bytestrings than the cereal based code (as in: cereal seems
to create a new Chunk whenever appending a lazy bytestring, whilst
Builder concats them into a single chunk, at least for the short strings
I've been using).

The Monoidal interface feels very natural, maybe even more natural than
the Monad interface of PutM in binary/cereal:

instance Argument a = Argument [a] where
put l = word32LE cnt  s
  where
   (cnt, s) = foldr (\e (c, m) - (c + 1, put e  m)) (0, mempty) l

Thanks,

Nicolas


___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] The state of binary (de)serialization

2013-02-28 Thread Nicolas Trangez
On Wed, 2013-02-27 at 07:49 +0100, Vincent Hanquez wrote:
 On Mon, Feb 25, 2013 at 01:30:40PM +0100, Nicolas Trangez wrote:
...
 I've been looking at the same thing lately, and i've been quite surprised, to
 say the least, by the usual go-to packages (cereal, binary). Performance wise
 this is hard to summarize, but if you serialize something small and have a 
 easy
 to compute size (e.g. fixed size structure), i would advise against using any
 kind of builder structure (builder,cereal,binary), and go directly at the
 Storable level, if performance need to be on-par other languages.
 
 My initial interpretation is that the builder initial cost is quite high, and
 only get amortized if the number of operations is quite high (and have less
 bytestrings). So if you have many structures encoded in one encoding operation
 it's probably ok-ish.
 
 I've made the following benchmark when i was doing my experiments,
 that shows basic serialization of bytestring-y data structures:
 
 * bclass is a simple function that use bytestring concat or append
 * bclass+io is a simple function that use mutable bytestring + poke to 
 create the bytestring
 * cereal is cereal's encode function
 * binary is binary's encode function
 * builder is bytestring's builder.
 
 * simple bytestring of constant size: sz
 * n bytestrings of same size: n*sz
 * n bytestrings of different size: sz+sz2+..
 * n bytestrings plus a w32 prefixed size: len+n*sz
 
 Obviously, caveat emptor:
 
 http://tab.snarc.org/others/benchmark-bytestring-serialization.html
 
 Let me know if anyone want the source file.

These are some really interesting (and very consistent) results, thanks!
I guess I should do some benchmarking myself and maybe change some thing
around (heck, now I'm using Builder to serialize constants :-P).

It might be worth to share these benchmarks with the 'binary' and
'bytestring'/'blaze-builder' maintainers?

Nicolas


___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


[Haskell-cafe] The state of binary (de)serialization

2013-02-25 Thread Nicolas Trangez
All,

In order to implement some network protocol clients recently, I needed
binary serialization of commands and deserialization of responses
('Command - ByteString' and 'ByteString - Response' functions,
preferably for both strict as well as lazy ByteStrings).

My go-to packages have always been 'binary' and 'cereal', but I was
wondering about the current (and future) state/goals:

- cereal supports chunk-based 'partial' parsing (runGetPartial). It
looks like support for this is introduced in recent versions of 'binary'
as well (runGetIncremental)
- cereal can output a strict bytestring (runPut) or a lazy one
(runPutLazy), whilst binary only outputs lazy ones (runPut)
- Next to binary and cereal, there's bytestring's Builder interface for
serialization, and Simon Meier's blaze-binary prototype

There are some blog posts and comments out there about merging cereal
and binary, is this what's the goal/going on (cfr runGetIncremental)?

In my use-case I think using Builder instead of binary/cereal's PutM
monad shouldn't be a major problem. Is this advisable performance-wise?

Overall: what's the advised future-proof strategy of handling binary
(de)serialization?

Thanks,

Nicolas


___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] performance question

2013-02-13 Thread Nicolas Trangez
On Wed, 2013-02-13 at 08:39 -0800, David Thomas wrote:
 One way in which regexps are foreign to Haskell-think is that, if
 they
 break, they generally break at run-time.  This could be ameliorated
 with
 template haskell

Care to elaborate on the ameliorate using TH part? I figure regexes
would be mostly used to parse some runtime-provided string, so how could
compile-TH provide any help?

Nicolas



___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Layer on a layer of record syntax in the type synonym?

2012-12-21 Thread Nicolas Trangez
On Fri, 2012-12-21 at 04:36 -0900, Christopher Howard wrote:
 Using a simple type I gave earlier from my monadic type question...
 
 code:
 
 data Socket3 a b c = Socket3 a b c
   deriving (Show)
 
 
 Is it possible somehow to layer on record syntax onto a synonym of the type?
 
 The idea would be something like this...
 
 code:
 
 type SpaceShip =
   Socket3 { engine :: Last Engine
   , hull :: Last Hull
   , guns :: [Guns]
   }
 
 
 ...purely for the convenience. But this doesn't seem to work with type
 as it assumes you are referring to already made constructors, and
 evidently newtype only allows use of a single record. I could wrap it
 in a normal data declaration but that would add an extra layer of
 complexity I think.

Although this 'Socket3' data type which all of a sudden should be
aliased as 'SpaceShip' feels/looks really strange (are you sure that's
the right way to reach whatever the goal is?), you could use lenses:

import Control.Lens

data Socket3 a b c = Socket3 a b c
  deriving (Show)

data Last a = Last a deriving Show
data Engine = Engine deriving Show
data Hull = Hull deriving Show
data Gun = Gun deriving Show

type SpaceShip = Socket3 (Last Engine) (Last Hull) [Gun]

engine :: Simple Lens SpaceShip (Last Engine)
engine = lens get lset
  where
get (Socket3 a _ _) = a
lset (Socket3 _ b c) a' = Socket3 a' b c

hull :: Simple Lens SpaceShip (Last Hull)
hull = lens get lset
  where
get (Socket3 _ b _ ) = b
lset (Socket3 a _ c) b' = Socket3 a b' c

guns :: Simple Lens SpaceShip [Gun]
guns = lens get lset
  where
get (Socket3 _ _ c) =  c
lset (Socket3 a b _) = Socket3 a b

main :: IO ()
main = do
print $ s0 ^. engine
print $ s0 ^. guns

let s1 = guns .~ [Gun, Gun] $ s0
print s1
print $ s1 ^. guns
  where
s0 :: SpaceShip
s0 = Socket3 (Last Engine) (Last Hull) []

(I'm no Lens expert so maybe there are better ways than manually
creating these Lens instances, or make them shorter/abstract something
out)

Nicolas


___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


[Haskell-cafe] (L)GPL libraries Haskell/GHC (was: Re: ANNOUNCE: tie-knot library)

2012-12-11 Thread Nicolas Trangez
Note: IANAL

On Tue, 2012-12-11 at 17:45 -0800, David Thomas wrote:
 On Tue, Dec 11, 2012 at 5:35 PM, Brandon Allbery allber...@gmail.comwrote:
 
  (Oddly enough, GPL is not the only open source license.)
 
 There was no implication to the contrary.  It was stated that BSD is a
 *weaker* license - this is true in the sense that it has fewer requirements
 (in particular, no copyleft) - and that strong copyleft licenses such as
 the GPL should be preferred as they do more to bolster the free software
 community.  You can disagree with this claim (there are arguments both ways
 - delving into them is not my point here) but please try not to bring in
 straw men.

Actually the library is made available under the LGPL-3 license,
according to its README, not the GPL (although the latter is implicit,
of course).

In the Haskell world this does have a different effect compared to when
one uses the LGPL for, say, a C library though, since (at least for now)
GHC uses/defaults to static linking, which IIRC (though IANAL) turns the
LGPL into GPL, so this has a severe impact for application authors. This
might be something people aren't aware of when releasing Haskell
libraries using the LGPL.

I tend to use the LGPL myself for most library-style projects, and do so
as well for Haskell code (although I'm aware of the drawbacks), but I'm
perfectly fine with people linking the libs statically as long as they
comply to the license as if they were using dynamic loading.

If anyone knows some standard license which boils down to obligations
like LGPL but OK for static linking as well, please let me know.

Nicolas


___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


[Haskell-cafe] ANN: zeromq3-conduit, Conduit bindings for zeromq3-haskell

2012-11-30 Thread Nicolas Trangez
Hi,

I published zeromq3-conduit, a small library which facilitates using
zeromq3-haskell, a binding for ZeroMQ 3.x, in a Conduit-based
application.

The 'examples' folder in the source repository contains ports of the
zeromq3-haskell examples.

The library also contains a module which might ease using plain
zeromq3-haskell: it lifts some of the IO actions into MonadIO and
provides a ReaderT which carries a Context around, so sockets can be
created without passing this around explicitly.

Package is on Hackage [1] and Github [2]. Comments/feedback/pull
requests/... welcome!

Nicolas

[1] http://hackage.haskell.org/package/zeromq3-conduit
[2] https://github.com/NicolasT/zeromq3-conduit/


___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Conduit and pipelined protocol processing using a threadpool

2012-11-28 Thread Nicolas Trangez
On Wed, 2012-11-28 at 09:17 +0200, Michael Snoyman wrote:
 
 
 
 On Tue, Nov 27, 2012 at 7:25 PM, Nicolas Trangez
 nico...@incubaid.com wrote:
 Michael,
 
 On Tue, 2012-11-27 at 17:14 +0200, Michael Snoyman wrote:
  I think the stm-conduit package[1] may be helpful for this
 use case.
  Each time you get a new command, you can fork a thread and
 give it the
  TBMChan to write to, and you can use sourceTBMChan to get a
 source to
  send to the client.
 
 
 That's +- what I had in mind. I did find stm-conduit before
 and did try
 to get the thing working using it, but these attempts failed.
 
 I attached an example which might clarify what I intend to do.
 I'm aware
 it contains several potential bugs (leaking threads etc), but
 that's
 beside the question ;-)
 
 If only I could figure out what to put on the 3 lines of
 comment I left
 in there...
 
 Thanks for your help,
 
 Nicolas
 
 
 
 The issue is that you're trying to put everything into a single
 Conduit, which forces reading and writing to occur in a single thread
 of execution. Since you want your writing to be triggered by a
 separate event (data being available on the Chan), you're running into
 limitations.
 
 
 The reason network-conduit provides a Source for the incoming data and
 a Sink for outgoing data is specifically to address your use case. You
 want to take the data from the Source and put it into the Chan in one
 thread, and take the data from the other Chan and put it into the Sink
 in a separate thread. Something like:
 
 
 myApp appdata = do
 chan1 - ...
 chan2 - ...
 replicateM_ 5 $ forkIO $ worker chan1 chan2
 forkIO $ appSource appdata $$ sinkTBMChan chan1
 sourceTBMChan chan2 $$ appSink appdata
 
 
 You'll also want to make sure to close chan1 and chan2 to make sure
 that your threads stop running.

Thanks, I +- figured that out last night. Only thing left is managing
the handshake before forking off the workers, if possible (otherwise
things become very messy IMHO), but ResumableSources etc might be of use
here.

Maybe there's a library somewhere in here...

Thanks a bunch,

Nicolas



___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


[Haskell-cafe] Conduit and pipelined protocol processing using a threadpool

2012-11-27 Thread Nicolas Trangez
All,

I've written a library to implement servers for some protocol using
Conduit (I'll announce more details later).

The protocol supports pipelining, i.e. a client can send a 'command'
which contains some opaque 'handle' chosen by the client, the server
processes this command, then returns some reply which contains this
handle. The client is free to send other commands before receiving a
reply for any previous request, and the server can process these
commands in any order, sequential or concurrently.

The library is based on network-conduit's Application style [1], as
such now I write code like (OTOH)

 application :: AppData IO - IO ()
 application client = appSource client $= handler $$ appSink client
   where
 handler = do
 negotiateResult - MyLib.negotiate
 liftIO $ validateNegotiateResult negotiateResult
 MyLib.sendInformation 123
 loop

loop = do
command - MyLib.getCommand
case command of
CommandA handle arg - do
result - liftIO $ doComplexProcessingA arg
MyLib.sendReply handle result
loop
Disconnect - return ()

This approach handles commands in-order, sequentially. Since command
processing can involve quite some IO operations to disk or network, I've
been trying to support pipelining on the server-side, but as of now I
was unable to get things working.

The idea would be to have a pool of worker threads, which receive work
items from some channel, then return any result on some other channel,
which should then be returned to the client.

This means inside loop I would have 2 sources: commands coming from
the client (using 'MyLib.getCommand :: MonadIO m = Pipe ByteString
ByteString o u m Command'), as well as command results coming from the
worker threads through the result channel. Whenever the first source
produces something, it should be pushed onto the work queue, and
whenever the second on yields some result it should be sent to the
client using 'MyLib.sendReply :: Monad m = Handle - Result - Pipe l i
ByteString u m ()'

I've been fighting this for a while and haven't managed to get something
sensible working. Maybe the design of my library is flawed, or maybe I'm
approaching the problem incorrectly, or ...

Has this ever been done before, or would anyone have some pointers how
to tackle this?

Thanks,

Nicolas

[1]
http://hackage.haskell.org/packages/archive/network-conduit/0.6.1.1/doc/html/Data-Conduit-Network.html#g:2



___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Conduit and pipelined protocol processing using a threadpool

2012-11-27 Thread Nicolas Trangez
Michael,

On Tue, 2012-11-27 at 17:14 +0200, Michael Snoyman wrote:
 I think the stm-conduit package[1] may be helpful for this use case.
 Each time you get a new command, you can fork a thread and give it the
 TBMChan to write to, and you can use sourceTBMChan to get a source to
 send to the client.

That's +- what I had in mind. I did find stm-conduit before and did try
to get the thing working using it, but these attempts failed.

I attached an example which might clarify what I intend to do. I'm aware
it contains several potential bugs (leaking threads etc), but that's
beside the question ;-)

If only I could figure out what to put on the 3 lines of comment I left
in there...

Thanks for your help,

Nicolas

{-# LANGUAGE Rank2Types #-}

module Main where

import Data.Conduit
import qualified Data.Conduit.List as CL
import Data.Conduit.TMChan

import Control.Applicative
import Control.Concurrent (forkIO)
import Control.Concurrent.STM (atomically)
import Control.Monad (forM_)
import Control.Monad.IO.Class (MonadIO, liftIO)

data Command = Add Int Int
 | Disconnect
  deriving (Show)
data Reply = Result Int
  deriving (Show)

application :: MonadIO m = GConduit Int m String
application = do
-- Create input and output channels to/from worker threads
(chanIn, chanOut) - liftIO $ (,) $ newTBMChanIO 10 * newTBMChanIO 10

-- Spawn some worker threads
liftIO $ forM_ [0..5] $ \i - forkIO $ processCommands i chanIn chanOut

-- How to make
-- sourceTBMChan chanOut
-- something of which all produced values are yield'ed by this Conduit?

loop chanIn
  where
-- Loop retrieves one command from our source and pushes it to the
-- worker threads input channel, then loops
loop :: MonadIO m = TBMChan Command - GConduit Int m String
loop chan = do
liftIO $ putStrLn Enter loop
cmd - getCommand
liftIO $ do
putStrLn $ Got command:  ++ show cmd
atomically $ writeTBMChan chan cmd
case cmd of
Disconnect - return ()
_ - loop chan

-- getCommand fetches and parses a single command from our source
getCommand :: Monad m = GSink Int m Command
getCommand = do
v - await
case v of
Nothing - return Disconnect
Just i - return $ Add i 1

-- processCommands reads commands from a given input channel, processes
-- them, and pushes the result to a given output channel
processCommands :: Int - TBMChan Command - TBMChan Reply - IO ()
processCommands i chanIn chanOut = do
putStrLn $ Enter processCommands  ++ show i
cmd - atomically $ readTBMChan chanIn
putStrLn $ show i ++  read command:  ++ show cmd
case cmd of
Nothing - return ()
Just (Add a b) - do
atomically $ writeTBMChan chanOut (Result (a + b))
putStrLn $ show i ++  pushed result
processCommands i chanIn chanOut
Just Disconnect - return ()


main :: IO ()
main = do
res - CL.sourceList [1..20] $= application $$ CL.consume
putStrLn $ Result:  ++ show res
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


[Haskell-cafe] Custom Enum instance with non-consecutive indices

2012-11-17 Thread Nicolas Trangez
All,

I've been working on a server implementation of an existing networking
protocol. The protocol uses magic constants in some places (e.g. to
tag message types), as well as bitfields, or a combination of both
packed in a single value.

I created data types for both the identifiers as well as the bitfield
masks, e.g.

 import Data.Bits

 data MessageType = Message1
  | Message2
  | Message5

 data MessageFlag = Flag1
  | Flag2

Since I need to be able to get a numeric representation of them, I
thought making a custom Enum instance would make sense:

 instance Enum MessageType where
 fromEnum a = case a of
 Message1 - 1
 Message2 - 2
 Message5 - 5
 toEnum n
 | n == 1 = Message1
 | n == 2 = Message2
 | n == 5 = Message5

 instance Enum MessageFlag where
 fromEnum a = case a of
 Flag1 - 1 `shiftL` 0
 Flag2 - 1 `shiftL` 1
 toEnum n
 | n == 1 `shiftL` 0 = Flag1
 | n == 1 `shiftL` 1 = Flag2

This is not a complete definition (not to mention non-exhaustive pattern
matches), so I was wondering what the best practices are to extend this
so these instances are 'correct'?

I've been trying several approaches, but all of them failed on code like

 getFlags :: Int - [MessageFlag]
 getFlags i = filter (\v - (i .. fromEnum v) /= 0) [Flag1 ..]

Unless I hard-code all options in the last list, of course, but this is
obviously not the intention.

Any help or pointers (including This is not how Enum is intended to be
used) would be appreciated!

Thanks,

Nicolas


___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Custom Enum instance with non-consecutive indices

2012-11-17 Thread Nicolas Trangez
On Sat, 2012-11-17 at 16:52 +0200, Roman Cheplyaka wrote:
 Hi Nicolas,
 
 The simplest approach would be to use the standard (derived) Enum
 instance that would be used for enumerations (like [Flag1..]), and
 have your own functions to convert to/from magic constants. 

Sure, but that kind-of defeats the purpose... fromEnum/toEnum would then
return some nonsensical integer value.

Nicolas


___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Custom Enum instance with non-consecutive indices

2012-11-17 Thread Nicolas Trangez
On Sat, 2012-11-17 at 16:27 +0100, Herbert Valerio Riedel wrote:
 what do you hope to gain from making your flags type an instance of
 the
 Enum class? 

Among others, the ability to list all flags using [Flag1 ..]

How is this handled for libraries wrapping C libs which use some bitset
structure?

Nicolas


___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] performance issues with popCount

2012-09-08 Thread Nicolas Trangez
On Fri, 2012-09-07 at 15:55 -0700, Johan Tibell wrote:
 On Fri, Sep 7, 2012 at 4:54 AM, Nicolas Trangez nico...@incubaid.com wrote:
  On Thu, 2012-09-06 at 12:07 -0700, Johan Tibell wrote:
  Have a look at the popCount implementation for e.g. Int, which are
  written in C and called through the FFI:
 
  https://github.com/ghc/packages-ghc-prim/blob/master/cbits/popcnt.c
 
  Out of interest: isn't this compiled into the popCnt# primop (and popcnt
  instruction on SSE4.2)?
 
 It's the other way around the popCnt# primop is compiled into either
 calls to these C functions or into the popcnt instruction, if -msse4.2
 is given.

Yes, indeed. I was referring to Data.Bits.popCount, but looking back
this was indeed completely non-obvious. My bad.

  I recently noticed Data.IntSet also contains a fairly basic bitcount
  implementation [1]. Is this kept as-is for a reason, instead of using
  popCount from Data.Bits?
 
 I don't think so, except that we want to support the last 3 released
 versions of GHC so we need to have a fallback if Data.Bits.popCount
 isn't defined.

I might look into creating a (CPP-based) patch then.

Nicolas


___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] performance issues with popCount

2012-09-07 Thread Nicolas Trangez
On Thu, 2012-09-06 at 12:07 -0700, Johan Tibell wrote:
 Have a look at the popCount implementation for e.g. Int, which are
 written in C and called through the FFI:
 
 https://github.com/ghc/packages-ghc-prim/blob/master/cbits/popcnt.c 

Out of interest: isn't this compiled into the popCnt# primop (and popcnt
instruction on SSE4.2)?

I recently noticed Data.IntSet also contains a fairly basic bitcount
implementation [1]. Is this kept as-is for a reason, instead of using
popCount from Data.Bits?

Nicolas

[1]
https://github.com/ghc/packages-containers/blob/master/Data/IntSet/Base.hs#L1459


___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


[Haskell-cafe] Vector: blit'ing a source into a destination

2012-09-02 Thread Nicolas Trangez
All,

For some code I need to alter an (unboxed or storable) vector by
blit'ing (copying) data from another (smaller) vector into it,
overwriting the existing data. I couldn't find a function for this in
the vector API, so I hacked something up which cuts the jobs (see
below), but it feels really ugly/dirty.

Any ideas about a better way to tackle this, and wouldn't this be a
useful addition to the standard API?

Thanks,

Nicolas


import Data.Vector.Unboxed (Unbox, Vector)
import qualified Data.Vector.Unboxed as UV
import qualified Data.Vector.Unboxed.Mutable as MUV

blit :: Unbox a = Vector a - Vector a - Int - Vector a
blit src dest offset = UV.modify act dest
  where
act dest' = do
let slice = MUV.slice offset len dest'

src' - UV.unsafeThaw src
MUV.copy slice src'

len = UV.length src

main :: IO ()
main = do
let v = UV.fromList [0 :: Int .. 10]
b = UV.fromList [20, 30, 40]

putStrLn $ v =  ++ show v
putStrLn $ b =  ++ show b
putStrLn $ blit b v 2 =  ++ show (blit b v 2)

-- v = fromList [0,1,2,3,4,5,6,7,8,9,10]
-- b = fromList [20,30,40]
-- blit b v 2 = fromList [0,1,20,30,40,5,6,7,8,9,10]


___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


[Haskell-cafe] Memory corruption issues when using newAlignedPinnedByteArray, GC kicking in?

2012-07-10 Thread Nicolas Trangez
All,

While working on my vector-simd library, I noticed somehow memory I'm
using gets corrupted/overwritten. I reworked this into a test case, and
would love to get some help on how to fix this.

Previously I used some custom FFI calls to C to allocate aligned memory,
which yields correct results, but this has a significant (+- 10x)
performance impact on my benchmarks. Later on I discovered the
newAlignedPinnedByteArray# function, and wrote some code using this.

Here's what I did in the test case: I created an MVector instance, with
the exact same implementation as vector's
Data.Vector.Storable.Mutable.MVector instance, except for basicUnsafeNew
where I pass one more argument to mallocVector [1].

I also use 3 different versions of mallocVector (depending on
compile-time flags):

mallocVectorOrig [2]: This is the upstream version, discarding the
integer argument I added.

Then here's my first attempt, very similar to the implementation of
mallocPlainForeignPtrBytes [3] at [4] using GHC.* libraries.

Finally there's something similar at [5] which uses the 'primitive'
library.

The test case creates vectors of increasing size, then checks whether
they contain the expected values. For the default implementation this
works correctly. For both others it fails at some random size, and the
values stored in the vector are not exactly what they should be.

I don't understand what's going on here. I suspect I lack a reference
(or something along those lines) so GC kicks in, or maybe the buffer
gets relocated, whilst it shouldn't.

Basically I'd need something like

GHC.ForeignPtr.mallocPlainAlignedForeignPtrBytes :: Int - Int - IO
(ForeignPtr a)

Thanks,

Nicolas

[1] https://gist.github.com/3084806#LC37
[2] https://gist.github.com/3084806#LC119
[3]
http://hackage.haskell.org/packages/archive/base/latest/doc/html/src/GHC-ForeignPtr.html
[4] https://gist.github.com/3084806#LC100
[5] https://gist.github.com/3084806#LC81




___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] vector-simd: some code available, and some questions

2012-07-08 Thread Nicolas Trangez
On Sun, 2012-07-08 at 20:49 +1000, Reiner Pope wrote:
 I've not been following this thread very closely, but it seems like
 what you're trying to do may be related to Geoffrey Mainland's work on
 SIMD support in GHC. See [1] for his SIMD-enabled version of the
 vector library. He's also written some blog posts about this [2].

Thanks. I knew about this before (did at least some research ;-)), yet I
think the scope is somewhat different (assuming my playground work has
any scope at all...).

I think Geoffreys work goes much further than what I'm trying to
accomplish: it's not my intention to write SIMD-based code at a high
level (which is, obviously, a great thing, but beyond my capabilities as
of now I'm afraid). What I'd like to achieve is to be able to write SIMD
code at the C level (or have SIMD code generated somehow through
LLVM/Clang(/Poly?), ISPC or others), and call into this from Haskell,
providing some guarantees w.r.t. alignment (and maybe length-in-bytes as
well?) of the passed vector pointers (which you don't get when using
plain Storable vectors as far as I could find/see).

Consider it a very short-term stop-gap solution until the tools are in
place to write high-level code which yields the same performance as a
more low-level (assembly-level) implementation.

Nicolas


___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] vector-simd: some code available, and some questions

2012-07-08 Thread Nicolas Trangez
On Sun, 2012-07-08 at 10:27 +0200, Gábor Lehel wrote:
 On Sun, Jul 8, 2012 at 3:05 AM, Nicolas Trangez nico...@incubaid.com wrote:
  I implemented the inductive alignment calculation over One and Twice
  (good idea, and easy to do), but I don't get the thing about
  superclasses. I've been trying several approaches (including definitions
  based on forall and other trickery I never used before), but didn't get
  things to work, at least: the compiler always said I'd need
  UndecidableInstances, and that sounds scary... Care to elaborate?
 
 All I meant was
 
 class (Alignment n, Alignment a) = AlignedToAtLeast n a
 
 but I got a bit ahead of myself, because that rules out the instance
 on tuples.

Maybe that's one of the things I ran into, can't remember OTOH.

  (I suppose you *could* write some kind of Alignment
 instance for them, taking their minimum or something, but that's
 getting a bit too subversive for me).

Heh, it already feels evil-but-in-a-good-and-powerful-way to me right
now ;-) Thanks for all your input!

  The alternative, if you want
 both Alignment as a superclass and the ability to constrain multiple
 types at once, is to have the above, remove the instance on tuples,
 and instead something like:
 
 class (AlignedToAtLeast n a, AlignedToAtLeast n b) = AlignedToAtLeast2 n a b
 instance (AlignedToAtLeast n a, AlignedToAtLeast n b) = AlignedToAtLeast2 n 
 a b
 class (AlignedToAtLeast n a, AlignedToAtLeast n b, AlignedToAtLeast n
 c) = AlignedToAtLeast3 n a b c
 instance (AlignedToAtLeast n a, AlignedToAtLeast n b, AlignedToAtLeast
 n c) = AlignedToAtLeast3 n a b c
 (feel free to think of better names!)
 
 unsafeXorSSE42 :: (Storable a, SV.AlignedToAtLeast3 SV.A16 o1 o2 o3)
 = SV.Vector o1 a - SV.Vector o2 a - SV.Vector o3 a

Implemented in [1]. Code says

unsafeXorSSE42 :: (Storable a,
SV.AlignedToAtLeast3 SV.A16 o1 o2 o3) =
SV.Vector o1 a - SV.Vector o2 a - SV.Vector o3 a

ghci says

unsafeXorSSE42
  :: (AlignedToAtLeast (Data.Vector.SIMD.Mutable.Twice A8) o2,
  AlignedToAtLeast (Data.Vector.SIMD.Mutable.Twice A8) o1,
  AlignedToAtLeast (Data.Vector.SIMD.Mutable.Twice A8) o3,
  Foreign.Storable.Storable a) =
 Vector o1 a - Vector o2 a - Vector o3 a

which is the same thing, so should do.

 That will require UndecidableInstances, but all that means is that GHC
 can't prove to itself that instance checking will terminate. So you
 could end up getting the compiler into an infinite loop (or in
 practice, to exceed its recursion limit). But it doesn't allow
 anything unsafe to happen at runtime, and there's plenty of perfectly
 good instances which terminate even if GHC can't prove it.

I see. I had some rather unsafe/undecidable-by-a-developer things in
mind, but I guess I should read up on some of the language extensions
GHC provides.

Thanks,

Nicolas

[1]
https://github.com/NicolasT/vector-simd/commit/8f934891c9630a96ce009fafa7f6ba70df306d4f





___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


[Haskell-cafe] vector-simd: some code available, and some questions

2012-07-07 Thread Nicolas Trangez
All, 

After my message of yesterday [1] I got down to it and implemented
something along those lines. I created a playground repository
containing the code at [2]. Initial benchmark results at [3]. More about
the benchmark at the end of this email.

First some questions and requests for help:

- I'm stuck with a typing issue related to 'sizeOf' calculation at [4].
I tried a couple of things, but wasn't able to figure out how to fix it.
- I'm using unsafePerformIO at [5], yet I'm not certain it's OK to do
so. Are there better (safer/performant/...) ways to get this working?
- Currently Alignment phantom types (e.g. A8 and A16) are not related to
each other: a function (like Data.Vector.SIMD.Algorithms.unsafeXorSSE42)
can have this signature:

unsafeXorSSE42 :: Storable a = SV.Vector SV.A16 a - SV.Vector SV.A16 a
- SV.Vector SV.A16 a

Yet, imaging I'd have an SV.Vector SV.A32 Word8 vector at hand, the
function should accept it as well (a 32-byte aligned vector is also
16-byte aligned). Is there any way to encode this at the type level?

That's about it :-)

As of now, I only implemented a couple of the vector API functions (the
ones required to execute my benchmark). Adding the others should be
trivial.

The benchmark works with Data.Vector.{Unboxed|Storable}.Vector (UV and
SV) vectors of Word8 values, as well as my custom
Data.Vector.SIMD.Vector type (MV) using 16-byte alignment (MV.Vector
MV.A16 Word8).

benchUV, benchSV and benchMV all take 2 pre-calculated Word8 vectors of
given size (1024 and 4096) and xor them pairwise into the result using
zipWith xor. benchMVA takes 2 suitable MV vectors and xor's them into
a third using a rather simple and unoptimized C implementation using
SSE4.2 intrinsics [6]. This could be enhanced quite a bit (I guess using
the prim calling convention, FFI overhead can be reduced as well).
Currently, only vectors of a multiple of 32 bytes are supported (mostly
because of laziness on my part).

As you can see, the zipWith Data.Vector.SIMD implementation is slightly
slower than the Data.Vector.Storable based one. I didn't perform much
profiling yet, but I suspect allocation and ForeignPtr creation is to
blame, this seems to be highly optimized in
GHC.ForeignPtr.mallocPlainForeignPtrBytes as used by
Data.Vector.Storable.

Thanks for any input,

Nicolas

[1] http://www.haskell.org/pipermail/haskell-cafe/2012-July/102167.html
[2] https://github.com/NicolasT/vector-simd/
[3] http://linode2.nicolast.be/files/vector-simd-xor1.html
[4]
https://github.com/NicolasT/vector-simd/blob/master/src/Data/Vector/SIMD/Algorithms.hs#L46
[5]
https://github.com/NicolasT/vector-simd/blob/master/src/Data/Vector/SIMD/Algorithms.hs#L43
[6]
https://github.com/NicolasT/vector-simd/blob/master/cbits/vector-simd.c#L47


___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] vector-simd: some code available, and some questions

2012-07-07 Thread Nicolas Trangez
On Sat, 2012-07-07 at 21:59 +0200, Gábor Lehel wrote:
 An alternative solution is to encode all of the alignments in unary,
 which is more general; if they're all going to be a power of two you
 can store just the logarithm:
 
 data One
 data Twice n -- not practical to call it Double :)
 
 class AlignedToAtLeast n a
 instance AlignedToAtLeast One One
 instance AlignedToAtLeast One (Twice a)
 instance AlignedToAtLeast n a = AlignedToAtLeast (Twice n) (Twice a)
 
 type A1 = One
 type A4 = Twice (Twice A1)
 type A8 = Twice A4
 type A16 = Twice A8
 type A32 = Twice A16
 
 and you can apply the same private class thing from above if you
 want. 

Very ingenious, thanks! I pushed this into [1], although export lists of
all modules most likely will need some love once things get into shape.

This also allows functions to become more general:

unsafeXorSSE42 :: (Storable a,
SV.AlignedToAtLeast SV.A16 o1, SV.Alignment o1,
SV.AlignedToAtLeast SV.A16 o2, SV.Alignment o2,
SV.AlignedToAtLeast SV.A16 o3, SV.Alignment o3) =
SV.Vector o1 a - SV.Vector o2 a - SV.Vector o3 a

I wonder whether GHC's upcoming type-level numerals could be useful in
this situation as well.

Nicolas

[1]
https://github.com/NicolasT/vector-simd/commit/a4f13745eb24d87a3628af13109f3e1d8232c925


___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] vector-simd: some code available, and some questions

2012-07-07 Thread Nicolas Trangez
On Sat, 2012-07-07 at 21:13 +0200, Nicolas Trangez wrote:
 As you can see, the zipWith Data.Vector.SIMD implementation is slightly
 slower than the Data.Vector.Storable based one. I didn't perform much
 profiling yet, but I suspect allocation and ForeignPtr creation is to
 blame, this seems to be highly optimized in
 GHC.ForeignPtr.mallocPlainForeignPtrBytes as used by
 Data.Vector.Storable.

I got the MV benchmark on-par with SV by reworking the allocation
mechanism: no more FFI involved, but based on
GHC.Exts.newAlignedPinnedByteArray# and some other trickery, see [1].
This could still be improved a little by using PlainPtr, but this is not
exported by GHC.ForeignPtr.

This did have a pretty big performance-impact on the SIMD-based
benchmark, compare [2] to the old one [3]. I have no clue why the 4096
case now only uses twice the time of the 1024 one, unlike the expected
4x (+- as before).

Nicolas

[1]
https://github.com/NicolasT/vector-simd/commit/5ec539167254435ef4e7d308706dcafae09504d2
[2] http://linode2.nicolast.be/files/vector-simd-xor2.html
[3] http://linode2.nicolast.be/files/vector-simd-xor1.html


___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] vector-simd: some code available, and some questions

2012-07-07 Thread Nicolas Trangez
On Sun, 2012-07-08 at 01:40 +0200, Gábor Lehel wrote:
  unsafeXorSSE42 :: (Storable a,
  SV.AlignedToAtLeast SV.A16 o1, SV.Alignment o1,
  SV.AlignedToAtLeast SV.A16 o2, SV.Alignment o2,
  SV.AlignedToAtLeast SV.A16 o3, SV.Alignment o3) =
  SV.Vector o1 a - SV.Vector o2 a - SV.Vector o3 a
 
 I wonder if you could get that a bit shorter... I suppose you could write:
 
 instance (AlignedToAtLeast n a, AlignedToAtLeast n b) =
 AlignedToAtLeast n (a, b)
 instance (AlignedToAtLeast n a, AlignedToAtLeast n b, AlignedToAtLeast
 n c) = AlignedToAtLeast n (a, b, c)
 ...and so on...

Once again, nifty! And implemented in [1].

 though it feels a little strange semantically (relating a tuple to a
 scalar), but I don't see what harm can come of it. And then you can
 just write SV.AlignedToAtLeast SV.A16 (o1, o2, o3) in signatures.

 You
 can also make (Alignment n, Alignment a) a superclass constraint of
 AlignedToAtLeast, and write instances for Alignment inductively on One
 and Twice, and then you don't have to write Alignment o1 etc.
 separately either. So the signature would be just:
 
 unsafeXorSSE42 :: (Storable a, SV.AlignedToAtLeast SV.A16 (o1, o2,
 o3)) =  SV.Vector o1 a - SV.Vector o2 a - SV.Vector o3 a
 
 which is friendlier.

I implemented the inductive alignment calculation over One and Twice
(good idea, and easy to do), but I don't get the thing about
superclasses. I've been trying several approaches (including definitions
based on forall and other trickery I never used before), but didn't get
things to work, at least: the compiler always said I'd need
UndecidableInstances, and that sounds scary... Care to elaborate?

Thanks!

Nicolas

[1]
https://github.com/NicolasT/vector-simd/commit/aedf25460b410e04a3d103befea59ebcb3903fdc


___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


[Haskell-cafe] vector, alignment and SIMD through FFI

2012-07-06 Thread Nicolas Trangez
Hello Cafe,

Recently I've been playing with the implementation of an algorithm, for
which we already have highly-optimized implementations available (in
plain C/C++ as well as OCaml with calls to C through FFI).

The algorithm works on buffers/arrays/vectors/whatever you want to call
it, which needs to be combined in certain ways. This can be highly
optimized by using SIMD instructions (like the ones provides by several
SSE versions).

I'd like to get a to Haskell version which is comparable in efficiency
as the existing versions, whilst remaining as 'functional' as possible.
I don't mind jumping into some low-level C glue and FFI (using ccall or
custom primops), but this should be limited.

Currently I have something working (still highly unoptimized) using
(unboxed) vectors from the vector package, using mutable versions within
a well-contained ST environment in some places.

One hot zone of the current version is combining several vectors, and
the performance of this operation could be greatly improved by using
SIMD instructions. There's one catch though: when using these, memory
should be aligned on certain boundaries (16 byte in this case).

First and foremost, to be able to pass my vectors to some C functions, I
should change my code into using Storable vectors (which should be fine,
I guess I can expect similar performance characteristics?). I couldn't
find any information on alignment guarantees of these vectors though...

Which is how I get to my question: are there any such guarantees? If
not, are there any pointers to how to proceed with this? I guess
tracking alignment at the type level should be the goal, you can find
some code trying to explain my reasoning up to now at the end of this
email.

I have some issues with this:

- I'd need to re-implement almost all vector operations, which seems
stupid.
- It doesn't actually work right now ;-)
- It'd be nice to be able to encode 'compatible' alignment: as an
example, a 16 byte aligned buffer is also 8 byte aligned...

I hope the above explains somewhat my goal. Any thoughts  help on this
would be very welcome!

Thanks,

Nicolas


module Data.Vector.SIMD (
-- ...
) where

import qualified Data.Vector.Storable as SV

import Foreign.Storable (Storable, sizeOf)
import Foreign.Ptr (Ptr, FunPtr)
import Foreign.ForeignPtr (ForeignPtr, newForeignPtr)
import System.IO.Unsafe (unsafePerformIO)

class Alignment a where
alignment :: a - Int

data A8Byte
instance Alignment A8Byte where
alignment _ = 8

data A16Byte
instance Alignment A16Byte where
alignment _ = 16

newtype Alignment a = SIMDVector a b = V (SV.Vector b)

replicate :: (Alignment a, Storable b) = a - Int - b - SIMDVector a
b
replicate a n b = V v
  where
ptr = unsafePerformIO $ do
v - _mm_malloc n (alignment a)
-- memset etc
return v

v = SV.unsafeFromForeignPtr0 ptr n

-- These are 2 _stub versions of the procedures since xmminstr.h (or
mm_malloc.h
-- when using GCC) contains them as inline procedures which are not
available
-- as-is in a library. There should be some C module which exports
-- _mm_malloc_stub and _mm_free_stub, which simply includes xmminstr.h
and calls
-- the underlying procedures.
foreign import ccall _mm_malloc_stub _mm_malloc_stub :: Int - Int -
IO (Ptr a)
foreign import ccall _mm_free_stub _mm_free_stub :: FunPtr (Ptr a -
IO ())


_mm_malloc :: Storable a = Int - Int - IO (ForeignPtr a)
_mm_malloc s l = do
-- This fails:
-- Ambiguous type variable `a0' in the constraint:
--   (Storable a0) arising from a use of `sizeOf'
-- v - c_mm_malloc (s * sizeOf (undefined :: a)) l
newForeignPtr _mm_free_stub undefined

-- This allocates a 16 byte aligned output buffer, takes 2 existing ones
and
-- calls some FFI function to perform some magic.
-- The implementation could run inside ST, if the FFI import (which e.g.
works
-- on a mutable buffer and returns IO ()) is lifted into ST using
unsafeIOToST
mySIMDFun :: SIMDVector A16Byte a - SIMDVector A16Byte a - SIMDVector
A16Byte a
mySIMDFun a b = undefined


___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] vector, alignment and SIMD through FFI

2012-07-06 Thread Nicolas Trangez
On Fri, 2012-07-06 at 13:43 -0700, Thomas DuBuisson wrote:
 On Fri, Jul 6, 2012 at 1:06 PM, Nicolas Trangez nico...@incubaid.com wrote:
  -- This fails:
  -- Ambiguous type variable `a0' in the constraint:
  --   (Storable a0) arising from a use of `sizeOf'
 
 Here you can either tie a type knot using proxy types or you can use
 the scoped type variable language extension.

Guess I'll have to do some reading ;-) Thanks.

 Perhaps I'm missing something specific to your use, but for the
 alignment issue you should be OK just calling allocBytes or one of its
 variants.  I made some noise about this a bit ago and it resulted in
 some extra words in the report under mallocBytes:
 
 
 The block of memory is sufficiently aligned for any of the basic
 foreign types that fits into a memory block of the allocated size.
 
 
 Which I'm pretty sure GHC did, and still does, follow.

Hmh... as far as I could find, mallocBytes basically does what malloc(3)
does, which is 8-byte alignment if I'm not mistaken on my x86-64 Linux
system. I could use those and the over-allocate-and-offset tricks,
but... that's ugly unless strictly necessary ;-)

Normally posix_memalign or memalign or valloc or _mm_malloc should
provide what I need as-is.

Except, when using those and vector's unsafeFromForeignPtr0, all I get
is a Vector a, which no longer has any alignment information in the
type, so I can't write a function which only accepts N-aligned vectors.
As a result, I'd need to be very careful only to pass aligned vectors to
it (checking manually), add code to handle pre/post-alignment bytes in
my SIMD functions (slow and stupid), or live with it and let my
application crash at random.

I found some work by Oleg Kiselyov and Chung-chieh Shan at [1] which
might be related, yet as of now I feel like that's too general for my
purpose (e.g. I don't see how to integrate it with vector).

Thanks,

Nicolas

[1] http://okmij.org/ftp/Haskell/types.html#ls-resources


___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


[Haskell-cafe] Long-running request/response protocol server using enumerator/iterator/iterIO/pipes/conduits/...

2012-06-26 Thread Nicolas Trangez
Hello Cafe,

Some time ago I tried to implement a network service using iteratee (or
enumerator, can't remember), but gave up in the end. More recently I
wanted to create something similar (a similar protocol), but failed
again.

So I'm looking for some example code or something similar (Google only
helped slightly).

First of all, I don't care which API/library to use, I guess for my
purpose all of enumerator, iteratee, iterIO, pipes, conduits,... are OK,
so all feedback is welcome.

Here's the catch. Most examples out there implement some server which
accepts a single client request, interprets it, creates a response,
returns this, and closes the connection (or something alike, think
HTTP).

The protocol I'd like to implement is different: it's long-running using
repeated requests  responses on a single client connection. Basically,
a client connects and sends some data to the server (where the length of
this data is encoded in the header). Now the server reads  parses this
(binary) data, sets up some initial state for this client connection
(e.g. opening a file handle), and returns a reply. Now the client can
send another request, server parses/interprets it using the connection
state, sends a reply, and so on.

Might sound easy (and actually it's pretty easy in most other languages
I know, including an OCaml implementation), yet I fail to figure out how
to get this done using some enumerator-style library.

Thanks for any help, I'll most likely write up something if I get things
working for future reference.

Nicolas


___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Long-running request/response protocol server using enumerator/iterator/iterIO/pipes/conduits/...

2012-06-26 Thread Nicolas Trangez
On Tue, 2012-06-26 at 21:32 +0200, Christopher Done wrote:
 On 26 June 2012 21:22, Nicolas Trangez nico...@incubaid.com wrote:
  Might sound easy (and actually it's pretty easy in most other languages
  I know, including an OCaml implementation), yet I fail to figure out how
  to get this done using some enumerator-style library.
 
 Well, it's easy in Haskell, too. Just use the standard libraries.

Sure, that could work.

 If you want to mess around with these still-in-research iteratees and
 eumerators for the composability then go for it, but when it's hard or
 weird, you can't really blame that on the language. :-)

Make no mistake, I'm not blaming anything except my own inability to
figure this out ;-)

Thanks,

Nicolas


___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Long-running request/response protocol server using enumerator/iterator/iterIO/pipes/conduits/...

2012-06-26 Thread Nicolas Trangez
On Tue, 2012-06-26 at 22:39 +0300, Michael Snoyman wrote:
 I've run into those kinds of problems in the past as well. In general,
 interleaving of data streams can be difficult with enumerator. That's
 the reason I added connect-and-resume to conduit. I use the technique
 in warp[1], which in fact *does* support multiple request/response
 pairs due to connection keep-alive. But the code base isn't the
 easiest introduction to the technique. If there's interest, I'll try
 to put together a blog post on using connect-and-resume to solve this
 kind of problem.

Thank you, Michael. I thought about HTTP keep-alive as well, but felt
reluctant to start by looking at a 'large' codebase like warp... Anyway,
what you point to seems reasonable to interpret, I should be able to
write something similar based on this (even though I never used
Conduits/ResourceT before).

Thanks!

Nicolas


___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] haskell tcp server

2012-01-18 Thread Nicolas Trangez
On Thu, 2012-01-19 at 13:12 +, Alexander V Vershilov wrote:
 Hello.
 
 I'm interested if there exists some library like warp but only for tcp.
 Or maybe some web page with skeleton for such server or with some
 variants, eg. concurent/single-threaded. I know that each service can
 have it's specific properties and realization, but there are many common
 things left.
 
 If it matter — my main task is to create server for protobuf protocol,
 maybe for such a task there are already created solutions.

You could take a look at
https://github.com/jamwt/haskell-scalable-server

Nicolas


___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] __GLASGOW_HASKELL__ for GHC 7.4

2012-01-17 Thread Nicolas Trangez
On Tue, 2012-01-17 at 15:35 +0400, Eugene Kirpichov wrote:
 Hi,
 
 I'm fixing a build error in a package that depends on the RTS API, which
 changed in 7.4, using #if __GLASGOW_HASKELL__ = 740.
 
 However, build log shows that __GLASGOW_HASKELL__ is still 704, not 740 as
 I'd expect.
 
 Is this a bug?

I don't think so. I recently came across [1]:

'''
Stable Releases
Stable branches are numbered x.y, where y is even. Releases on the
stable branch x.y are numbered x.y.z, where z (= 1) is the patchlevel
number. Patchlevels are bug-fix releases only, and never change the
programmer interface to any system-supplied code. However, if you
install a new patchlevel over an old one you will need to recompile any
code that was compiled against the old libraries.

The value of __GLASGOW_HASKELL__ (see Section 4.11.3, “Options affecting
the C pre-processor”) for a major release x.y.z is the integer xyy (if y
is a single digit, then a leading zero is added, so for example in
version 6.8.2 of GHC we would have __GLASGOW_HASKELL__==608).
'''

As such, release 7.4.0 would yield __GLASGOW_HASKELL__ 704.

Nicolas

[1]
http://www.haskell.org/ghc/docs/7.0.4/html/users_guide/version-numbering.html


___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] State Machine Composition

2011-12-21 Thread Nicolas Trangez
On Wed, 2011-12-21 at 18:34 +, Daniel Waterworth wrote:
 I made this simple state machine combinator library today. I think it
 works as a simple example of a good use for GADTs.
 
 https://gist.github.com/1507107

Any way to do something along the lines of

type StateChange a = SC a a

handleChange :: Monad m = StateChange ConnectionState - m ()
handleChange (SC Closed Opening) = return ()
handleChange (SC Opening Closed) = return ()
handleChange (SC Closed Open) = return ()

where the last line would yield a type checking error at compile time,
and the compiler can warn about handleChange not being exhaustive (for
the valid state change steps)?

Nicolas


___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe