Re: [Haskell-cafe] Parsec and Text
Yes, thanks ! When I saw it, I wondered if Antoine added the instance for Stream Text because of my question ;) The thing is that it adds a dependency to parsec, but since Text is more efficient than String it might not me much of a congestion. 2011/10/9 Ozgur Akgun ozgurak...@gmail.com Hi. See the following for the recent announcement: http://permalink.gmane.org/gmScrubs - 3x08 - My Friend the Doctorane.comp.lang.haskell.general/18972http://permalink.gmane.org/gmane.comp.lang.haskell.general/18972 On 8 October 2011 18:37, Yves Parès limestr...@gmail.com wrote: Is there a package that allows parsing Text with parsec, ... HTH, Ozgur ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Best bit LIST data structure
I am not aware of such a library, but IMHO this code will be very simple. data Bits b = BitList b = BitList Int {- number of used bits in the next component -} b [b] Write an isomorphism between @BitList b@ and @ListStep (BitList b)@ where data ListStep e rc = Nil | Cons e rc On 07.10.11 17:52, Ryan Newton wrote: Hi Cafe, We are lucky to have a plethora of data structures out there. But it does make choosing one off hackage difficult at times. In this case I'm *not* looking for a O(1) access bit vector (Data.Vector.Unboxed seems to be the choice there), but an efficient representation for a list of bits (cons,head,tail). Let's say that you want to represent tree indices as you walk down a binary tree. [Bool] is a simple choice, you only add to the front of the list (0/1 = Left/Right), sharing the tails. But [Bool] is quite space inefficient. Something like [Int] would allow packing the bits more efficiently. A Lazy ByteString could amortize the space overhead even more... but in both cases there's a tiny bit of work to do in wrapping those structures for per-bit access. That's probably the right thing but I wanted to check to see if there's something else recommended, perhaps more off-the-shelf. What about just using the Data.Bits instance of Integer? Well, presently, the setBit instance for very large integers creates a whole new integer, shifts, and xors: http://haskell.org/ghc/docs/latest/html/libraries/base/src/Data-Bits.html#setBit (I don't know if it's possible to do better. From quick googling GMP seems to use an array of limbs rather than a chunked list, so maybe there's no way to treat large Integers as a list and update only the front...) Advice appreciated! Thanks, -Ryan ___ 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] Best bit LIST data structure
Yep, it is simple. But I prefer to only use well-tested data structure libraries where I can! Here's an example simple implementation (partial -- missing some common functions): module Data.BitList ( BitList , cons, head, tail, empty , pack, unpack, length, drop ) where import Data.Int import Data.Bits import Prelude as P hiding (head,tail,drop,length) import qualified Data.List as L import Test.HUnit data BitList = One {-# UNPACK #-} !Int {-# UNPACK #-} !Int64 | More {-# UNPACK #-} !Int {-# UNPACK #-} !Int64 BitList instance Show BitList where show bl = BitList ++ show (map (\b - case b of True - '1'; False - '0') (unpack bl)) -- show bl = pack ++ show (unpack bl) empty :: BitList empty = One 0 0 cons :: Bool - BitList - BitList cons True x@(One 64 _ ) = More 1 1 x cons False x@(One 64 _ ) = More 1 0 x cons True x@(More 64 bv _) = More 1 1 x cons False x@(More 64 bv _) = More 1 0 x cons True(One i bv) = One (i+1) (bv `setBit` i) cons False (One i bv) = One (i+1) (bv ) cons True(More i bv r) = More (i+1) (bv `setBit` i) r cons False (More i bv r) = More (i+1) (bv ) r -- TODO: May consider (More 0 _ _) representation to reduce extra -- allocation when size of the BitList is fluctuating back and forth. head :: BitList - Bool head (One 0 _ ) = error tried to take head of an empty BitList head (More 0 _ r) = error BitList: data structure invariant failure! head (One i bv ) = bv `testBit` (i-1) head (More i bv r) = bv `testBit` (i-1) tail :: BitList - BitList tail (One 0 _ ) = error tried to take the tail of an empty BitList tail (One i bv ) = One (i-1) bv tail (More 1 bv r) = r tail (More i bv r) = More (i-1) bv r pack :: [Bool] - BitList pack [] = One 0 0 pack (h:t) = cons h (pack t) unpack :: BitList - [Bool] unpack (One 0 _) = [] unpack (One i bv)= (bv `testBit` (i-1)) : unpack (One (i-1) bv) unpack (More 0 _ r) = unpack r unpack (More i bv r) = (bv `testBit` (i-1)) : unpack (More (i-1) bv r) drop :: Int - BitList - BitList drop 0 bl = bl drop n bl | n = 64 = case bl of One _ _- error drop: not enough elements in BitList More i _ r - drop (n-i) r drop n bl = case bl of One i bv - One (i-n) bv More i bv r - More (i-n) bv r length :: BitList - Int length (One i _) = i length (More i _ r) = i + length r -- TODO: index, take, etc -- TODO: functor instance, etc. -- Testing: t1 = pack (L.concat$ L.replicate 10 [True,False,True]) t2 = L.length $ unpack $ pack $ replicate 1000 True t3 = pack $ replicate 1000 True t4 = drop 500 t3 p3 = L.and (unpack t3) p4 = L.and (unpack t4) t5 = iterate tail t4 !! 250 t5a = length t5 t5b = L.length (unpack t5) tests :: Test tests = TestList [ show t1 ~=? BitList \101101101101101101101101101101\ , t2 ~=? 1000 , t5a ~=? 250 , t5b ~=? 250 , p3 ~=? True , p4 ~=? True ] -- TODO: QuickCheck On Sun, Oct 9, 2011 at 7:50 AM, Roman Beslik ber...@ukr.net wrote: I am not aware of such a library, but IMHO this code will be very simple. data Bits b = BitList b = BitList Int {- number of used bits in the next component -} b [b] Write an isomorphism between @BitList b@ and @ListStep (BitList b)@ where data ListStep e rc = Nil | Cons e rc On 07.10.11 17:52, Ryan Newton wrote: Hi Cafe, We are lucky to have a plethora of data structures out there. But it does make choosing one off hackage difficult at times. In this case I'm *not* looking for a O(1) access bit vector (Data.Vector.Unboxed seems to be the choice there), but an efficient representation for a list of bits (cons,head,tail). Let's say that you want to represent tree indices as you walk down a binary tree. [Bool] is a simple choice, you only add to the front of the list (0/1 = Left/Right), sharing the tails. But [Bool] is quite space inefficient. Something like [Int] would allow packing the bits more efficiently. A Lazy ByteString could amortize the space overhead even more... but in both cases there's a tiny bit of work to do in wrapping those structures for per-bit access. That's probably the right thing but I wanted to check to see if there's something else recommended, perhaps more off-the-shelf. What about just using the Data.Bits instance of Integer? Well, presently, the setBit instance for very large integers creates a whole new integer, shifts, and xors: http://haskell.org/ghc/docs/latest/html/libraries/base/src/Data-Bits.html#setBit (I don't know if it's possible to do better. From quick googling GMP seems to use an array of limbs rather than a chunked list, so maybe there's no way to treat large Integers as a list and update only the front...) Advice appreciated! Thanks, -Ryan ___ Haskell-Cafe mailing
Re: [Haskell-cafe] Best bit LIST data structure
Hi, Am Freitag, den 07.10.2011, 10:52 -0400 schrieb Ryan Newton: What about just using the Data.Bits instance of Integer? Well, presently, the setBit instance for very large integers creates a whole new integer, shifts, and xors: http://haskell.org/ghc/docs/latest/html/libraries/base/src/Data-Bits.html#setBit (I don't know if it's possible to do better. From quick googling GMP seems to use an array of limbs rather than a chunked list, so maybe there's no way to treat large Integers as a list and update only the front...) interesting idea. Should this be considered a bug in ghc? (Not that it cannot represent the result, but that it crashes even out of ghci): $ ghci GHCi, version 7.0.4: http://www.haskell.org/ghc/ :? for help Loading package ghc-prim ... linking ... done. Loading package integer-gmp ... linking ... done. Loading package base ... linking ... done. Prelude :m + Data.Bits Prelude Data.Bits setBit 0 (2^63-1::Int) gmp: overflow in mpz type Abgebrochen Greetings, Joachim -- Joachim nomeata Breitner m...@joachim-breitner.de | nome...@debian.org | GPG: 0x4743206C xmpp: nome...@joachim-breitner.de | http://www.joachim-breitner.de/ signature.asc Description: This is a digitally signed message part ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Best bit LIST data structure
On Sunday 09 October 2011, 15:54:14, Joachim Breitner wrote: Hi, Am Freitag, den 07.10.2011, 10:52 -0400 schrieb Ryan Newton: What about just using the Data.Bits instance of Integer? Well, presently, the setBit instance for very large integers creates a whole new integer, shifts, and xors: http://haskell.org/ghc/docs/latest/html/libraries/base/src/Data-Bits.h tml#setBit (I don't know if it's possible to do better. From quick googling GMP seems to use an array of limbs rather than a chunked list, so maybe there's no way to treat large Integers as a list and update only the front...) interesting idea. Should this be considered a bug in ghc? (Not that it cannot represent the result, but that it crashes even out of ghci): $ ghci GHCi, version 7.0.4: http://www.haskell.org/ghc/ :? for help Loading package ghc-prim ... linking ... done. Loading package integer-gmp ... linking ... done. Loading package base ... linking ... done. Prelude :m + Data.Bits Prelude Data.Bits setBit 0 (2^63-1::Int) gmp: overflow in mpz type Abgebrochen says info gmp: `_mp_size' and `_mp_alloc' are `int', although `mp_size_t' is usually a `long'. This is done to make the fields just 32 bits on some 64 bits systems, thereby saving a few bytes of data space but still providing plenty of range. So it seems to be GMP itself. ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Best bit LIST data structure
On 9 October 2011 14:54, Joachim Breitner m...@joachim-breitner.de wrote: Hi, Am Freitag, den 07.10.2011, 10:52 -0400 schrieb Ryan Newton: What about just using the Data.Bits instance of Integer? Well, presently, the setBit instance for very large integers creates a whole new integer, shifts, and xors: http://haskell.org/ghc/docs/latest/html/libraries/base/src/Data-Bits.html#setBit (I don't know if it's possible to do better. From quick googling GMP seems to use an array of limbs rather than a chunked list, so maybe there's no way to treat large Integers as a list and update only the front...) interesting idea. Should this be considered a bug in ghc? (Not that it cannot represent the result, but that it crashes even out of ghci): $ ghci GHCi, version 7.0.4: http://www.haskell.org/ghc/ :? for help Loading package ghc-prim ... linking ... done. Loading package integer-gmp ... linking ... done. Loading package base ... linking ... done. Prelude :m + Data.Bits Prelude Data.Bits setBit 0 (2^63-1::Int) gmp: overflow in mpz type Abgebrochen Yes, that's a bug. GMP shouldn't call abort(), but it should be turned into a Haskell exception. It probably doesn't make much of a difference in practise, but safe could should never crash GHC. ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] SMP parallelism increasing GC time dramatically
It would be really useful to see the threadscope output for this. Apart from cache effects (which may well be significant at 12 cores), the usual problems with parallel GHC are synchronisation. When GHC wants to perform a parallel GC it needs to stop all Haskell threads. These are lightweight threads and are scheduled cooperatively, i.e., there's no way to interrupt them from the outside (except for the OS, but that doesn't help with GC). Usually, a thread is able to yield whenever it tries to do an allocation which is common enough in normal Haskell. However, your work contains lots of matrix computation which likely don't do allocations in the inner loop or call C to do their work, which isn't interruptible, either. My guess would be that (at least part of) the reason for your slowdown is that the parallel GC spends a lot of time waiting for threads to stop. This would be apparent in Threadscope. (I may be wrong, because even the single-threaded GC needs to stop all threads) On 7 October 2011 18:21, Tom Thorne thomas.thorn...@gmail.com wrote: I have made a dummy program that seems to exhibit the same GC slowdown behavior, minus the segmentation faults. Compiling with -threaded and running with -N12 I get very bad performance (3x slower than -N1), running with -N12 -qg it runs approximately 3 times faster than -N1. I don't know if I should submit this as a bug or not? I'd certainly like to know why this is happening! import Numeric.LinearAlgebra import Numeric.GSL.Special.Gamma import Control.Parallel.Strategies import Control.Monad import Data.IORef import Data.Random import Data.Random.Source.PureMT import Debug.Trace -- subsets s n = (subsets_stream s) !! n subsets_stream [] = [[]] : repeat [] subsets_stream (x:xs) = let r = subsets_stream xs s = map (map (x:)) r in [[]] : zipWith (++) s (tail r) testfun :: Matrix Double - Int - [Int] - Double testfun x k cs = lngamma (det (c+u)) where (m,c) = meanCov xx m' = fromRows [m] u = (trans m') m' xx = fromColumns ( [(toColumns x)!!i] ++ [(toColumns x)!!j] ++ [(toColumns x)!!k] ) i = cs !! 0 j = cs !! 1 test :: Matrix Double - Int - Double test x i = sum p where p = parMap (rdeepseq) (testfun x (i+1)) (subsets [0..i] 2) ranMatrix :: Int - RVar (Matrix Double) ranMatrix n = do xs - mapM (\_ - mapM (\_ - uniform 0 1.0) [1..n]) [1..n] return (fromLists xs) loop :: Int - Double - Int - RVar Double loop n s i = traceShow i $ do x - ranMatrix n let r = sum $ parMap (rdeepseq) (test x) [2..(n-2)] return (r+s) main = do let n = 100 let iter = 5 rng - newPureMT rngr - newIORef rng p - runRVar (foldM (loop n) 0.0 [1..iter]) rngr print p I have also found that the segmentation faults in my code disappear if I switch from Control.Parallel to Control.Monad.Par, which is quite strange. I get slightly better performance with Control.Parallel when it completes without a seg. fault, and the frequency with which it does so seems to depend on the number of sparks that are being created. On Thu, Oct 6, 2011 at 1:56 PM, Tom Thorne thomas.thorn...@gmail.com wrote: I'm trying to narrow it down so that I can submit a meaningful bug report, and it seems to be something to do with switching off parallel GC using -qg, whilst also passing -Nx. Are there any known issues with this that people are aware of? At the moment I am using the latest haskell platform release on arch. I'd like to give 7.2 a try in case that fixes it, but I'm using rather a lot of libraries (hmatrix, fclabels, random fu) and I don't know how to install them for multiple ghc versions On Wed, Oct 5, 2011 at 10:43 PM, Johan Tibell johan.tib...@gmail.com wrote: On Wed, Oct 5, 2011 at 2:37 PM, Tom Thorne thomas.thorn...@gmail.com wrote: The only problem is that now I am getting random occasional segmentation faults that I was not been getting before, and once got a message saying: Main: schedule: re-entered unsafely Perhaps a 'foreign import unsafe' should be 'safe'? I think this may be something to do with creating a lot of sparks though, since this occurs whether I have the parallel GC on or not. Unless you (or some library you're using) is doing what the error message says then you should file a GHC bug here: http://hackage.haskell.org/trac/ghc/ -- Johan ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe -- Push the envelope. Watch it bend. ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Best bit LIST data structure
Yes, if you do not use high-level concepts and optimize everything by hand, it requires a lot of testing. :) ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Best bit LIST data structure
Must it be a list? What about a Bloom Filter? On Sun, Oct 9, 2011 at 9:11 AM, Roman Beslik ber...@ukr.net wrote: Yes, if you do not use high-level concepts and optimize everything by hand, it requires a lot of testing. :) ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe -- -- Regards, KC ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] thespian thoughts
Hi Alexander, I went looking for something to clean up rss2irc's thread management, and your recently released thespian package looks like the simplest, most practical actors/erlang/OTP-ish lib for haskell so far. Thanks! I need to restart threads (actors) in a controlled way when they die or hang. I think some of all of that is also part of Erlang/OTP, and maybe it's already on your todo list. Here are some notes I made, for your interest and in case you have any further thoughts. I thought of adding some actor-transforming combinators like these: -- | Spawn the specified action and restart it whenever it dies, unless -- the restart frequency exceeds any of the given maximum frequencies in -- which case throw an exception. restart :: [Frequency] - IO a - IO Address restart fs action = spawn $ do setFlag TrapRemoteExceptions let start times = [] forever t - getCurrentTime update start times when (any fs exceeded by start times) throw error worker - spawn action monitor worker receive worker [Case _ - return ()] -- | Convert hangs to exceptions using a watchdog timer: spawn the -- specified action under the control of a watcher which monitors it and -- also kills it and throws an exception if the worker ever fails to -- send (something) to the watcher within the specified interval. watchdog :: Seconds - (Address - IO a) - IO Address watchdog t action = spawn $ do watcher - self worker - spawn $ action watcher monitor worker forever receiveTimeout t [Case _ - return () Default - throw error ] which I would use something like: main = do (feed, bot) - ... spawn $ do reader- restart [MaxPerHour 2] $ watchdog 60 $ feedReader feed bot announcer - restart [MaxPerHour 2] $ watchdog 60 $ ircAnnouncer bot responder - restart [MaxPerHour 2] $ watchdog 60 $ ircResponder bot monitor reader monitor announcer monitor responder setFlag TrapRemoteExceptions receive [Case e :: RemoteException - exitFailure (show e) -- one of the above died or hung too frequently ] but the types aren't right. I'm not sure if these combinators are possible with the current thespian api. Also they would complicate things, eg what is the address of a restarted actor ? On second thoughts it might be better if these features were built in to the library. I imagine something like: main = do ... reader- spawnWith [RestartSpec [MinInterval (minutes 5), MaxPerHour 3, MaxPerWeek 6], Watchdog (seconds 60)] $ feedReader feed bot feedReader = do forever poll feed, do stuff resetWatchdog What do you think ? Best - Simon___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] Package documentation complaints -- and a suggestion
Hi all Following a link from the Yesod book, I arrived at [1], curious to find out what groundhog was. Once there, I learned... nothing: This library provides just the general interface and helper functions. You must use a specific backend in order to make this useful. [1] http://hackage.haskell.org/package/groundhog Hoping to find more, I clicked on the top-level module. Once again, the text here was uninformative, though from the example it seems to be something to do with databases (and it is to be applauded for including an example in the docs). So, package authors: PLEASE, tell me what your package does in the description. Tell me *again* in the top-level haddocks (I may have come directly there by a link). And then, tell me where to look for more information. Instead of This module defines the functions and datatypes used throughout the framework. Most of them are for internal use, tell me which are *not* for internal use. Write documentation for people who don't know how to use your package. Some people prefer to have this outside of the haddocks (I don't like this because papers and blogs are less likely to stay up to date than what is embedded in the file, but for tutorials etc. a website might be more appropriate) but if so link to it from both the Haddocks and the package description. But I also have a concrete suggestion for Hackage: include the package synopsis on the package's page. The distinction between synopsis and description can be confusing, and sometimes it seems to violate DRY to have the same info in both. To the author of groundhog: I hope you are not offended by my picking on your package. It's not the only culprit -- just the one that pushed me over the edge. Of course, I would be pleased if this email encouraged you to fix it, but I am addressing this rant to the Haskell community because the problem is a cultural one. --Max ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Best bit LIST data structure
data *(Bits b) =* BitList b Is deprecated and soon to be removed from the language. I fail to understand. Why not just: data BitList b = Nil | BitList Int b (BitList b) ?? 2011/10/9 Roman Beslik ber...@ukr.net I am not aware of such a library, but IMHO this code will be very simple. data Bits b = BitList b = BitList Int {- number of used bits in the next component -} b [b] Write an isomorphism between @BitList b@ and @ListStep (BitList b)@ where data ListStep e rc = Nil | Cons e rc On 07.10.11 17:52, Ryan Newton wrote: Hi Cafe, We are lucky to have a plethora of data structures out there. But it does make choosing one off hackage difficult at times. In this case I'm *not* looking for a O(1) access bit vector (Data.Vector.Unboxed seems to be the choice there), but an efficient representation for a list of bits (cons,head,tail). Let's say that you want to represent tree indices as you walk down a binary tree. [Bool] is a simple choice, you only add to the front of the list (0/1 = Left/Right), sharing the tails. But [Bool] is quite space inefficient. Something like [Int] would allow packing the bits more efficiently. A Lazy ByteString could amortize the space overhead even more... but in both cases there's a tiny bit of work to do in wrapping those structures for per-bit access. That's probably the right thing but I wanted to check to see if there's something else recommended, perhaps more off-the-shelf. What about just using the Data.Bits instance of Integer? Well, presently, the setBit instance for very large integers creates a whole new integer, shifts, and xors: http://haskell.org/ghc/docs/latest/html/libraries/base/src/Data-Bits.html#setBit (I don't know if it's possible to do better. From quick googling GMP seems to use an array of limbs rather than a chunked list, so maybe there's no way to treat large Integers as a list and update only the front...) Advice appreciated! Thanks, -Ryan ___ Haskell-Cafe mailing listHaskell-Cafe@haskell.orghttp://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] Simple design question using Wai
Hello, I am trying to move a web application I wrote that initially used raw sockets for doing HTTP by hand to a more sensible Wai-based framework, and I am running into a design issue. I initially thought it would be a good idea to be able to support various I/O methods so I defined a layer called CommandIO (this is a game application) to insulate business-level code from the detials of reading commands and outputting results to the outside world. Here is the signature for this simple monad: class (Monad io) = CommandIO io where readCommand :: io Command writeResult :: CommandResult - io () then I have an interpret function which looks like: interpret :: (CommandIO io, Map t) = Commands t io CommandResult which reads a command from the io, execute it producing a CommandResult, then request output from the io using writeResult. This works nicely using Reader-based data containing a Handle, both for HTTP-based and console-based I/O. But when I try to move to WAI, I am a little bit stuck. The core of Wai is an application which rougly has type Request - Response and this basically breaks my (simple) model of read commands / write results. I suspect there might be a way to stick to my current model using enumerators/streams for I/O and a custom type for encapsulating the underlying state of the HTTP exchange. I also thought about reversing the dependency : ensuring that interpret does not need to know about low-level I/O and only dealing with Command/CommandResult, with I/O being handled by wrappers. Thanks in advance for any insights, Arnaud PS: the code is on github: http://github.com/abailly/crete1941. Not that I deem it ready for prime-time though... ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Simple design question using Wai
On Sun, Oct 9, 2011 at 3:57 PM, Arnaud Bailly arnaud.oq...@gmail.com wrote: Hello, I am trying to move a web application I wrote that initially used raw sockets for doing HTTP by hand to a more sensible Wai-based framework, and I am running into a design issue. I initially thought it would be a good idea to be able to support various I/O methods so I defined a layer called CommandIO (this is a game application) to insulate business-level code from the detials of reading commands and outputting results to the outside world. Here is the signature for this simple monad: class (Monad io) = CommandIO io where readCommand :: io Command writeResult :: CommandResult - io () then I have an interpret function which looks like: interpret :: (CommandIO io, Map t) = Commands t io CommandResult What is the 'Commands' type? What is the 'Map' class? which reads a command from the io, execute it producing a CommandResult, then request output from the io using writeResult. This works nicely using Reader-based data containing a Handle, both for HTTP-based and console-based I/O. But when I try to move to WAI, I am a little bit stuck. The core of Wai is an application which rougly has type Request - Response and this basically breaks my (simple) model of read commands / write results. I suspect there might be a way to stick to my current model using enumerators/streams for I/O and a custom type for encapsulating the underlying state of the HTTP exchange. I also thought about reversing the dependency : ensuring that interpret does not need to know about low-level I/O and only dealing with Command/CommandResult, with I/O being handled by wrappers. Your type class as written doesn't appear to work too well for HTTP - what would happen if I called 'readCommand' twice? Or called 'writeResult' before receiving a command? HTTP is, at its core, a server which responds to a single request with a single response. The WAI type reflects in a way that makes it hard to do wrong. This doesn't work because the API you want to provide makes it possible to do wrong. Your class might be able to fit into WAI if each back-end provided a single function: execute :: (Command - io CommandResult) - io () This should make sense for console, Handle-based and HTTP. Am I on the right track? Antoine ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Package documentation complaints -- and a suggestion
The package summary is Type-safe ADT-database mapping library., which gives some idea about what it does. In my experience, any package that starts its source files with {-# LANGUAGE GADTs, TypeFamilies, ExistentialQuantification, StandaloneDeriving, TypeSynonymInstances, MultiParamTypeClasses, FunctionalDependencies, FlexibleInstances, FlexibleContexts, OverlappingInstances, ScopedTypeVariables, GeneralizedNewtypeDeriving, UndecidableInstances, EmptyDataDecls #-} is probably an experiment in what is possible, rather than a production-friendly library. Many people upload experimental packages to Hackage so that they can be used by other interested people, even though the packages are not ready/intended for mass consumption. A lack of documentation in such cases is understandable. I wonder if it would be worth giving package uploaders control over whether their packages are shown on the package list? Packages can be manually hidden by emailing an admin, but that's a lot of trouble. ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Trouble using State Monad.
Hi David, Thanks for the reply. In trying to follow your advice, I arrived at this code: 17 newtype Filter e a = F { 18 runFilter :: EitherT e (State FilterState) a 19 } deriving (Monad, MonadState FilterState) 20 21 applyFilter :: Filter e a - FilterState - a - (Either e a, FilterState) 22 applyFilter f s x = runState (runEitherT (runFilter f)) s which compiles ok, but I don't know where to put the `x' on the right side of the `=' in line 22. That is, I still don't understand how I'm supposed to feed the input, `x', into the filter. Thanks, -db On Sat, Oct 8, 2011 at 5:27 PM, David Barbour dmbarb...@gmail.com wrote: On Sat, Oct 8, 2011 at 4:28 PM, Captain Freako capn.fre...@gmail.comwrote: 17 newtype Filter e a = F { * 18 runFilter :: EitherT e (State FilterState) a ** * 19 } deriving (Monad, MonadState FilterState) it compiles, but I can't figure out how I'd feed the input to the filter, in that case. Input to Filter would be modeled with: 'a - Filter e b'. I would rename your 'runFilter' to 'unFilter', then define a function 'runFilter' accepting an initial FilterState. Regards, - db ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Trouble using State Monad.
On Sun, Oct 9, 2011 at 7:57 PM, Captain Freako capn.fre...@gmail.comwrote: 21 applyFilter :: Filter e a - FilterState - a - (Either e a, FilterState) 22 applyFilter f s x = runState (runEitherT (runFilter f)) s I still don't understand how I'm supposed to feed the input, `x', into the filter. In 'Filter e a', a is an output type, not an input type. If you want inputs, you'll need constructors of the form (a - Filter e b). This might be closer to what you're looking for: applyFilter :: FilterState - (a - Filter e b) - a - (Either e b, FilterState) applyFilter s f x = runState (runEitherT (runFilter (f x))) s The burden of receiving input is then shifted to the functions that create 'Filter' operations. If you really want the input type to be part of the Filter type definition, you'll need to use arrows instead of monads. ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Simple design question using Wai
Hi Antoine, Thanks for your interest. On Sun, Oct 9, 2011 at 11:57 PM, Antoine Latter aslat...@gmail.com wrote: interpret :: (CommandIO io, Map t) = Commands t io CommandResult What is the 'Commands' type? What is the 'Map' class? More details here : https://github.com/abailly/crete1941/blob/master/CommandsInterpreter.hs This doesn't work because the API you want to provide makes it possible to do wrong. Your class might be able to fit into WAI if each back-end provided a single function: execute :: (Command - io CommandResult) - io () This should make sense for console, Handle-based and HTTP. Am I on the right track? Yes, sure. I actually think I over-engineered the whole thing and inverting the dependency might simplify a lot of things. The signature you provide is exactly what I was thinking about after posting my mail : simply a game-features focused request/response conversation wrapped by whatever I/O is needed. Arnaud ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] Seeking Feedback on Crypto Learning Project Ideas
Hi, I am a Haskell newbie looking for a small to medium size Haskell project that I can use as a learning tool, and would appreciate some feedback. I want to design and build something new, from scratch, that could actually be of practical use and that hasn't been done before (in Haskell, that is). I want to end up with a library package that could be uploaded to Hackage. I also want it to be something cryptography related, since this is a strong interest of mine. I'm particularly interested in exploring the possibilities of being able to pass basic crypto algorithms, to very generic higher-order functions quite naturally in Haskell. I would like to know a) if these ideas have been done (in Haskell) that I'm not aware of, b) which would be most useful/interesting to fellow Haskellers, c) guesstimates of the amount of work involved in each, d) suitability for learning language concepts, and e) any other helpful suggestions you might have Some specific project ideas I have been kicking around that i would appreciate feedback on: 1. An implementation of Shamir's Secret Sharing: http://en.wikipedia.org/wiki/Shamir%27s_Secret_Sharing 2. A Haskell binding to LibTomCrypt (Opinions for/against LibTom? - it looks unusually complete.) 3. A generic secure channel, where you pass your choice of basic algorithms (hash, symmetric, asymmetric, compression, etc) to higher order function 4. A Haskell implementation of Trevor Perrin's CryptoID's: http://trevp.net/cryptoID/index.html 5. A Haskell implementation of a generic Proof of Work system: http://en.wikipedia.org/wiki/Proof-of-work_system as a building block for anti-spam/anti-denial-of-service systems such as hashcash. 6. Some other generic high level interface to basic algorithms (looking for ideas here). I would also welcome any other project ideas along these lines that you might have. Thank you in advance. Dan Kelly ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe