Re: [Haskell-cafe] Please help me spot where space leak occur.

2011-07-27 Thread Jason Dagit
On Fri, Jul 22, 2011 at 1:54 AM, Olexander Kozlov ookoz...@gmail.com wrote:
 Jason, thank you for your help. The hint for using -s option is very
 valuable.
 It is good to see people answering questions about Haskell here on
 haskell-cafe.

stackoverflow is another good place to ask.

 This is really matter. I hope I will be helpfull some day too :)
 As for the question I didn't mention in my psot that Fn can be of arbitrary
 size.

You could extend my solution pretty easily to work for arbitrary size.

 Now I have another question which I'm concerned with. I used foldl' (strict)
 in my implementation
 instead of just foldl (lazy). Does it mean that libraries are to be in two
 implementations one strict
 and another one lazy? Because there no way to affect strictness/lazyness of
 function without modifying
 its implementation. I' going to ask this question as a separate thread.

It doesn't come up that much.  It comes up here with your foldl, with
Chans, modifyIORef, modifySTRef, and a few things like that.  But most
of the time you want a lazy version until you spot a space leak.  Most
of the time the library creator notices and makes a strict version as
needed.  One of the nice things about Haskell is that you get a choice
between lazy and strict, and lazy by default is nice in many ways.
Space leaks like this are not usually show stoppers for experienced
Haskell folks.

Good luck!
Jason

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


Re: [Haskell-cafe] Please help me spot where space leak occur.

2011-07-22 Thread Olexander Kozlov
Jason, thank you for your help. The hint for using -s option is very
valuable.

It is good to see people answering questions about Haskell here on
haskell-cafe.
This is really matter. I hope I will be helpfull some day too :)

As for the question I didn't mention in my psot that Fn can be of arbitrary
size.
I choosed 3 for simplicity. And with your solution I cannot match agains
list of arbitrary size.
But I have found the cause of memory consumption. To find it I started to
unfold test function
and found that the recursive call to compose is not strict.

Here is what I did with base implementation:

fna = [(1, 2), (2, 3), (3, 1)]
fni = [(1, 1), (2, 2), (3, 3)]

fldl compose fni (repl 5 fna)

fldl compose fni (fna : repl 4 fna)
fldl compose (compose fni fna) (repl 4 fna)
fldl compose (compose fni fna) (fna : repl 3 fna)
fldl compose (compose (compose fni fna) fna) (repl 3 fna)
fldl compose (compose (compose fni fna) fna) (fna : repl 2 fna)
fldl compose (compose (compose (compose fni fna) fna) fna) (repl 2 fna)
fldl compose (compose (compose (compose fni fna) fna) fna) (fna : repl 1
fna)
fldl compose (compose (compose (compose (compose fni fna) fna) fna) fna)
(repl 1 fna)
fldl compose (compose (compose (compose (compose fni fna) fna) fna) fna)
(fna : repl 0 fna)
fldl compose (compose (compose (compose (compose (compose fni fna) fna) fna)
fna) fna) (repl 0 fna)
fldl compose (compose (compose (compose (compose (compose fni fna) fna) fna)
fna) fna) []

compose (compose (compose (compose (compose ((1, 1) : (2, 2) : (3, 3) : [])
fna) fna) fna) fna) fna
compose (compose (compose (compose ((1, lkup 1 fna) : compose ((2, 2) : (3,
3) : []) fna) fna) fna) fna) fna
compose (compose (compose ((1, lkup (lkup 1 fna) fna) : compose (compose
((2, 2) : (3, 3) : []) fna) fna) fna) fna) fna
compose (compose ((1, lkup (lkup (lkup 1 fna) fna) fna) : compose (compose
(compose ((2, 2) : (3, 3) : []) fna) fna) fna) fna) fna
compose ((1, lkup (lkup (lkup (lkup 1 fna) fna) fna) fna) : compose (compose
(compose (compose ((2, 2) : (3, 3) : []) fna) fna) fna) fna) fna

(1, lkup (lkup (lkup (lkup (lkup 1 fna) fna) fna) fna) fna) : compose
(compose (compose (compose (compose ((2, 2) : (3, 3) : []) fna) fna) fna)
fna) fna
(1, lkup (lkup (lkup (lkup 2 fna) fna) fna) fna) : compose (compose (compose
(compose (compose ((2, 2) : (3, 3) : []) fna) fna) fna) fna) fna
(1, lkup (lkup (lkup 3 fna) fna) fna) : compose (compose (compose (compose
(compose ((2, 2) : (3, 3) : []) fna) fna) fna) fna) fna
(1, lkup (lkup 1 fna) fna) : compose (compose (compose (compose (compose
((2, 2) : (3, 3) : []) fna) fna) fna) fna) fna
(1, lkup 2 fna) : compose (compose (compose (compose (compose ((2, 2) : (3,
3) : []) fna) fna) fna) fna) fna
(1, 3) : compose (compose (compose (compose (compose ((2, 2) : (3, 3) : [])
fna) fna) fna) fna) fna

(1, 3) : (2, lkup (lkup (lkup (lkup (lkup 2 fna) fna) fna) fna) fna) :
compose (compose (compose (compose (compose ((3, 3) : []) fna) fna) fna)
fna) fna
(1, 3) : (2, lkup (lkup (lkup (lkup 3 fna) fna) fna) fna) : compose (compose
(compose (compose (compose ((3, 3) : []) fna) fna) fna) fna) fna
(1, 3) : (2, lkup (lkup (lkup 1 fna) fna) fna) : compose (compose (compose
(compose (compose ((3, 3) : []) fna) fna) fna) fna) fna
(1, 3) : (2, lkup (lkup 2 fna) fna) : compose (compose (compose (compose
(compose ((3, 3) : []) fna) fna) fna) fna) fna
(1, 3) : (2, lkup 3 fna) : compose (compose (compose (compose (compose ((3,
3) : []) fna) fna) fna) fna) fna
(1, 3) : (2, 1) : compose (compose (compose (compose (compose ((3, 3) : [])
fna) fna) fna) fna) fna

(1, 3) : (2, 1) : (3, lkup (lkup (lkup (lkup (lkup 3 fna) fna) fna) fna)
fna) : compose (compose (compose (compose (compose [] fna) fna) fna) fna)
fna
(1, 3) : (2, 1) : (3, lkup (lkup (lkup (lkup 1 fna) fna) fna) fna) : compose
(compose (compose (compose (compose [] fna) fna) fna) fna) fna
(1, 3) : (2, 1) : (3, lkup (lkup (lkup 2 fna) fna) fna) : compose (compose
(compose (compose (compose [] fna) fna) fna) fna) fna
(1, 3) : (2, 1) : (3, lkup (lkup 3 fna) fna) : compose (compose (compose
(compose (compose [] fna) fna) fna) fna) fna
(1, 3) : (2, 1) : (3, lkup 1 fna) : compose (compose (compose (compose
(compose [] fna) fna) fna) fna) fna
(1, 3) : (2, 1) : (3, 2) : compose (compose (compose (compose (compose []
fna) fna) fna) fna) fna

(1, 3) : (2, 1) : (3, 2) : []

The first thing I noticed is that fldl has to be strict to avoid n thunks
for compose evaluation.
The next thing is that compose itself has to be strict with both lkup and
recursive calls strict too.
If I left recursive call non-strict (that is where my problem was) I will
have n thunks for recursive
composition evaluation. If I left call to lkup non-strict I will have n
thunks for mapped value evaluation
for each member of Fn.

n is the amount functions I whant to compose with. I my example this is
1,000,000 functions.

Now I have another question which I'm concerned with. I used foldl' (strict)
in my implementation
instead of 

[Haskell-cafe] Please help me spot where space leak occur.

2011-07-21 Thread Olexander Kozlov
Greetings Haskell community,

I stuck with a space leak problem in simple task. I have a function
described with a list of pairs:

   type Fn a b = [(a, b)]

mapping values from a to b. And I have a composition operation which accepts
two functions and returns
theirs composition:

   compose :: Eq b = Fn a b - Fn b c - Fn a c

Finding composition of 1,000,000 functions takes about 240M with the
following implementation:

type Fn a b = [(a, b)]

lkup :: Eq a = a - Fn a b - b
lkup x ((a, b) : abs) = if x /= a then lkup x abs else b

compose :: Eq b = Fn a b - Fn b c - Fn a c

compose ((a, b) : abs) bcs = (a, lkup b bcs) : compose abs bcs
compose [] _ = []

fldl :: (a - b - a) - a - [b] - a

fldl f z (x:xs) = fldl f (f z x) xs
fldl _ z [] = z

fna = [(1, 2), (2, 3), (3, 1)]
fni = [(1, 1), (2, 2), (3, 3)]

test = fldl compose fni (replicate 100 fna)

main = print test

I build with:

   ghc --make -prof -auto-all -caf-all -fforce-recomp -rtsopts Test.hs

Profile results:

   Test.exe +RTS -K50M -p -RTS

total time  =0.34 secs   (17 ticks @ 20 ms)
total alloc = 240,003,820 bytes  (excludes profiling overheads)

COST CENTREMODULE   %time %alloc

composeMain  58.8   80.0
lkup   Main  35.30.0
test   Main   5.9   11.7
fldl   Main   0.08.3

After reading 'High-Performance Haskell' by Johan Tibell I tried to made my
compose function strict:

compose :: Eq b = Fn a b - Fn b c - Fn a c

compose ((a, b) : abs) bcs = let c = lkup b bcs in c `seq` (a, c) : compose
abs bcs
compose [] _ = []

and memory consuption reduced down to 180M. Good achievement but still too
much!

Profile results:

   Test.exe +RTS -K50M -p -RTS

total time  =0.24 secs   (12 ticks @ 20 ms)
total alloc = 180,003,820 bytes  (excludes profiling overheads)

COST CENTREMODULE   %time %alloc

composeMain  83.3   73.3
lkup   Main   8.30.0
fldl   Main   8.3   11.1
test   Main   0.0   15.6

I tried to make fldl strict as well:

fldl :: (a - b - a) - a - [b] - a

fldl f z (x:xs) = let z' = f z x in z' `seq` fldl f z' xs
fldl _ z [] = z

and end up with 160M of total allocations.

Profile results:

   Test.exe +RTS -K32M -p -RTS

total time  =0.30 secs   (15 ticks @ 20 ms)
total alloc = 160,003,820 bytes  (excludes profiling overheads)

COST CENTREMODULE   %time %alloc

composeMain  46.7   82.5
lkup   Main  40.00.0
test   Main   6.7   17.5
fldl   Main   6.70.0

Please help me spot where space leak occur, I see no other places for space
leaks. I'll appreciate any help.

(I intentionally wrote my own implementations of lookup and foldl to have
direct control on them.)
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Please help me spot where space leak occur.

2011-07-21 Thread Jason Dagit
On Thu, Jul 21, 2011 at 1:22 AM, Olexander Kozlov ookoz...@gmail.com wrote:
 Greetings Haskell community,
 I stuck with a space leak problem in simple task. I have a function
 described with a list of pairs:
    type Fn a b = [(a, b)]
 mapping values from a to b. And I have a composition operation which accepts
 two functions and returns
 theirs composition:
    compose :: Eq b = Fn a b - Fn b c - Fn a c
 Finding composition of 1,000,000 functions takes about 240M with the
 following implementation:
 type Fn a b = [(a, b)]
 lkup :: Eq a = a - Fn a b - b
 lkup x ((a, b) : abs) = if x /= a then lkup x abs else b
 compose :: Eq b = Fn a b - Fn b c - Fn a c
 compose ((a, b) : abs) bcs = (a, lkup b bcs) : compose abs bcs
 compose [] _ = []
 fldl :: (a - b - a) - a - [b] - a
 fldl f z (x:xs) = fldl f (f z x) xs
 fldl _ z [] = z
 fna = [(1, 2), (2, 3), (3, 1)]
 fni = [(1, 1), (2, 2), (3, 3)]
 test = fldl compose fni (replicate 100 fna)
 main = print test
 I build with:
    ghc --make -prof -auto-all -caf-all -fforce-recomp -rtsopts Test.hs
 Profile results:
   Test.exe +RTS -K50M -p -RTS
 total time  =        0.34 secs   (17 ticks @ 20 ms)
 total alloc = 240,003,820 bytes  (excludes profiling overheads)
 COST CENTRE                    MODULE               %time %alloc
 compose                        Main                  58.8   80.0
 lkup                           Main                  35.3    0.0
 test                           Main                   5.9   11.7
 fldl                           Main                   0.0    8.3
 After reading 'High-Performance Haskell' by Johan Tibell I tried to made my
 compose function strict:
 compose :: Eq b = Fn a b - Fn b c - Fn a c
 compose ((a, b) : abs) bcs = let c = lkup b bcs in c `seq` (a, c) : compose
 abs bcs
 compose [] _ = []
 and memory consuption reduced down to 180M. Good achievement but still too
 much!
 Profile results:
   Test.exe +RTS -K50M -p -RTS
 total time  =        0.24 secs   (12 ticks @ 20 ms)
 total alloc = 180,003,820 bytes  (excludes profiling overheads)
 COST CENTRE                    MODULE               %time %alloc
 compose                        Main                  83.3   73.3
 lkup                           Main                   8.3    0.0
 fldl                           Main                   8.3   11.1
 test                           Main                   0.0   15.6
 I tried to make fldl strict as well:
 fldl :: (a - b - a) - a - [b] - a
 fldl f z (x:xs) = let z' = f z x in z' `seq` fldl f z' xs
 fldl _ z [] = z
 and end up with 160M of total allocations.
 Profile results:
   Test.exe +RTS -K32M -p -RTS
 total time  =        0.30 secs   (15 ticks @ 20 ms)
 total alloc = 160,003,820 bytes  (excludes profiling overheads)
 COST CENTRE                    MODULE               %time %alloc
 compose                        Main                  46.7   82.5
 lkup                           Main                  40.0    0.0
 test                           Main                   6.7   17.5
 fldl                           Main                   6.7    0.0
 Please help me spot where space leak occur, I see no other places for space
 leaks. I'll appreciate any help.

The space leak is because your fldl is not as strict as is needed.
This version of the program needs about 1 meg on my computer:
{-# LANGUAGE BangPatterns #-}
type Fn a b = [(a, b)]

lkup :: Eq a = a - Fn a b - b
lkup x ((a, b) : abs) = if x /= a then lkup x abs else b

compose :: Eq b = Fn a b - Fn b c - Fn a c

compose ((a, b) : abs) bcs = (a, lkup b bcs) : compose abs bcs
compose [] _ = []

-- fldl :: (a - b - a) - a - [b] - a
fldl f z (x:xs) =
  let z'@[(!z1,!z2),(!z3,!z4),(!z5,!z6)] = f z x
  in z' `seq` fldl f z' xs
fldl _ z [] = z

fna = [(1, 2), (2, 3), (3, 1)]
fni = [(1, 1), (2, 2), (3, 3)]

test = fldl compose fni (replicate 100 fna)

main = print test


$ Test +RTS -K50M -p -s -RTS
[(1,2),(2,3),(3,1)]
 351,125,156 bytes allocated in the heap
 108,576 bytes copied during GC
  26,888 bytes maximum residency (1 sample(s))
  18,168 bytes maximum slop
   1 MB total memory in use (0 MB lost due to fragmentation)

  Generation 0:   669 collections, 0 parallel,  0.00s,  0.00s elapsed
  Generation 1: 1 collections, 0 parallel,  0.00s,  0.00s elapsed

  INIT  time0.00s  (  0.01s elapsed)
  MUT   time0.50s  (  0.50s elapsed)
  GCtime0.00s  (  0.00s elapsed)
  RPtime0.00s  (  0.00s elapsed)
  PROF  time0.00s  (  0.00s elapsed)
  EXIT  time0.00s  (  0.00s elapsed)
  Total time0.50s  (  0.51s elapsed)

  %GC time   0.0%  (0.5% elapsed)

  Alloc rate703,371,486 bytes per MUT second

  Productivity 100.0% of total user, 98.4% of total elapsed

When checking for a space leak, I find the output of +RTS -s -RTS more
helpful than the allocation stats in the .prof:

$ cat Test.prof
Thu Jul 21 05:12 2011 Time and Allocation Profiling Report  (Final)

   Test.exe +RTS -K50M -p -s

Re: [Haskell-cafe] Please help me debug my arrow

2010-01-20 Thread Paul Johnson

On 18/01/10 20:33, Paul Johnson wrote:


I'm going nuts looking at this.  Can anyone see what I'm doing wrong?

I found the problem eventually.  Its a scoping problem with rt1 in the 
(.) function when composeSP gets called recursively.



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


[Haskell-cafe] Please help me debug my arrow

2010-01-18 Thread Paul Johnson

Hi,

I'm trying to write an arrow for a real-time stream processor.  I'm 
basing it on the SP type in Hughes paper on Generalising Monads to 
Arrows (http://www.cs.chalmers.se/~rjmh/Papers/arrows.pdf) section 6.  
I've extended this with a notion of time by making each step a function 
of time.  But I can't get the compose operator to work.


The arrow itself is defined in http://haskell.pastebin.com/m49944f64 
with the (.) function highlighted.  Some simple tests are in 
http://haskell.pastebin.com/m6d90f27 with the problematic call highlighted.


When run it produces an infinite list of puts, which causes the 
SimulateRTSP interpreter function to diverge.  But I've run the 
expansions by hand, and they seem to work (see the test case file at the 
bottom).


I'm going nuts looking at this.  Can anyone see what I'm doing wrong?

Thanks,

Paul.


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


[Haskell-cafe] Re: please help me to find errors from my first app

2008-08-10 Thread Changying Li
thanks. I know how to do it. I should treat it as a stream. 
-- 

Thanks  Regards

Changying Li

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


Re: [Haskell-cafe] please help me to find errors from my first app

2008-08-09 Thread Scott Turner
On 2008 August 08 Friday, Changying Li wrote:
 I want to write a reverse proxy like perlbal to practive haskell. Now I
 just write a very simple script to forward any request to
 www.google.com.

 but it dosn't work. I run command ' runhaskell Proxy.hs'  and 'wget
 http://localhost:8080/'. but wget just wait forever and runhaskkell can
 get request. when I break wget, the 'runhaskell' can print response
 returned from www.google.com.

The problem is with
   request - hGetContents hRequest
which blocks until wget closes the connection.  Using lazy bytestrings just 
defers the problem slightly. Your processRequest blocks when the 'request' 
string is used.

For some insight into how this can be avoided, see hGetBufNonBlocking.  I'm 
not familiar enough with the Haskell libraries to point you to the ideal 
solution.
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


[Haskell-cafe] please help me to find errors from my first app

2008-08-08 Thread Changying Li
Hi. 
I want to write a reverse proxy like perlbal to practive haskell. Now I
just write a very simple script to forward any request to
www.google.com.

but it dosn't work. I run command ' runhaskell Proxy.hs'  and 'wget
http://localhost:8080/'. but wget just wait forever and runhaskkell can
get request. when I break wget, the 'runhaskell' can print response
returned from www.google.com. 
why?

module Main where

import System.Posix.Process
import Network
import Prelude hiding (putStr)
import System.IO hiding (hGetContents, putStr)

import Control.Concurrent
import System.Posix.Signals
import Data.ByteString.Lazy.Char8 (hGetContents, hPut, putStr,hGet,cons)
listenPort = PortNumber 8080
connectToHost = 208.67.219.230
connectToPort = PortNumber 80

main :: IO ()
main = do
  hSetBuffering stdout NoBuffering
  socket - listenOn listenPort
  let doLoop = do
 (hdl, _, _) - accept socket
 forkIO $ processRequest hdl
 doLoop
  doLoop

processRequest :: Handle - IO ()
processRequest hRequest = do
  installHandler sigPIPE Ignore Nothing; 
  hSetBuffering hRequest NoBuffering
  hSetBuffering stdout NoBuffering
  request - hGetContents hRequest
  putStr $ '' `cons` (' ' `cons` request)
  hResponse - connectTo connectToHost connectToPort
  hSetBuffering hResponse NoBuffering
  hPut hResponse request
  response - hGetContents hResponse
  putStr $ '' `cons` (' ' `cons` response)
  hPut hRequest response
  hClose hRequest
  hClose hResponse





-- 

Thanks  Regards

Changying Li

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


[Haskell-cafe] Haskell scripting system (please help me simplify the design)

2005-10-27 Thread Joel Reymont

Folks,

With lots of help from #haskell and haskell-cafe I came up with the  
following setup. It's working fine but requires quite a bit of  
boilerplate code. Could you please help me simplify it?


I apologize for the very long message and will describe any parts  
that are unclear. Please ask away. This is my first Haskell code,  
written over the course of 3 weeks (1 week to learn Haskell) so I'm  
bound to get some things wrong or unoptimal. Still, I'm quite amazed  
that I have been able to get this to work and to work correctly in  
such a short time span.


The system is basically a scripting engine to test a poker server  
that lets you write simple scripts. I went out of my way to enable QA  
techs to use as little Haskell as possible, thus I'm treating all  
poker commands/packets as a list of properties.


What I found is that I'm writing a lot of boiler-plate code to handle  
the convertion of property values into storables. I think this  
dovetails into the recent GADT discussion. I wonder if my design and  
interaction between Packet, Convertible, Prop and Attr can be  
simplified.


These are a couple of sample scripts (incomplete):

---
module Test where

import Script
import Handshake as H

script env =
do setDebugLevel 100
   dotimes 1 $ launch $ H.script []
   waitForChildren
---

module Handshake where

import Script

script env =
-- connect to server
do world - connect env 192.168.0.197 15667
   -- setup callbacks
   world - add world [
   [ onCmd := CmdHandshake Server,
 call := onServerHandshake ],
   [ onCmd := CmdConnectGame Server,
 call := onConnectGame ],
   [ onCmd := CmdServerInfo Server,
 call := onServerInfo ],
   [ onCmd := CmdLogon Server,
 call := onLogon ],
   [ onCmd := CmdGameInfo Server,
 call := onGameInfo ],
   [ onCmd := CmdMoney Server,
 call := onMoney ]
  ]
   -- start handshake
   send world $ make (CmdHandshake Invalid) []
   run world

onServerHandshake cmd world =
do send world $ make (CmdConnectGame Client)
[ localIP := 10.0.0.2,
  affiliateID := [28] ]
   return world

onServerInfo cmd world =
do send world $ make (CmdLogon Client) [ name := foo,
  password := bar,
  affiliateID := [28] ]
   -- retrieve table id
   tables' - get tables cmd
   debug 99 $ Tables:  ++ show tables'
   tableID' - get tableID $ head tables'
   debug 99 $ TableID:  ++ show tableID'
   debug 99 $ World:  ++ show world
   -- save it for later use
   world - set (tableID := tableID') world
   -- return updated info
   return world

onGameInfo cmd world =
do debug 99 Got game!
   stop world

---

I'm describing binary packets using properties (from WxHaskell) with  
the added twist that when you say attr := value you can specify what  
value will be converted to for storage.


This is how I would use the system...

This describes the properties for the admin message and wait list  
init commands. I would use the properties to serialize the commmands.


cmdProps (CmdAdminMessage Server) = [ title := ,
  message := ,
  postAction := 0 ]

cmdProps (CmdSrvWaitListInit Server) = [ waitListTables := [] ]

I also have a dictionary that describes the attributes such as  
title, message, postAction, etc. I'm allowing deeply nested lists of  
properties.


title :: Attr String WString = makeAttr title
message :: Attr String WString = makeAttr message
postAction :: Attr Word8 Word8 = makeAttr postAction
waitListTables  :: Attr [TableID] (FixedList Word8 (LE TableID)) =
   makeAttr waitListTables

Attr String WString means that a String is accepted on the right-hand  
side and the string will be converted into a wide string for storage.  
Same thing with a list of table ids that is converted into a list of  
little-endian table ids (word32s) prefixed by a Word8 length for  
storage.


The conversion/casting is done with code like this:

class Convertible a b where
convert_AB :: a - b
convert_BA :: b - a

instance Convertible [Word8] FastString where
convert_AB a = packWords a
convert_BA b = unpackWords b

instance Convertible Bool Bool where
convert_AB a = a
convert_BA b = b

instance Convertible Bool Word8 where
convert_AB True = 1
convert_AB False = 0
convert_BA 1 = True
convert_BA 0 = False

instance Convertible String WString where
convert_AB a = WString $ FS.pack a
convert_BA (WString b) = FS.unpack b

Re: [Haskell-cafe] Haskell scripting system (please help me simplify the design)

2005-10-27 Thread Robert Dockins
On Oct 27, 2005, at 11:01 AM, Joel Reymont wrote:Folks,With lots of help from #haskell and haskell-cafe I came up with the following setup. It's working fine but requires quite a bit of boilerplate code. Could you please help me simplify it?I apologize for the very long message and will describe any parts that are unclear. Please ask away. This is my first Haskell code, written over the course of 3 weeks (1 week to learn Haskell) so I'm bound to get some things wrong or unoptimal. Still, I'm quite amazed that I have been able to get this to work and to work correctly in such a short time span.Welcome to Haskell!The system is basically a scripting engine to test a poker server that lets you write simple scripts. I went out of my way to enable QA techs to use as little Haskell as possible, thus I'm treating all poker commands/packets as a list of properties.What I found is that I'm writing a lot of boiler-plate code to handle the convertion of property values into "storables". I think this dovetails into the recent GADT discussion. I wonder if my design and interaction between Packet, Convertible, Prop and Attr can be simplified.[snip]My concern is mostly with a lot of similar boilerplate code required for casting, specially in very alike cases like the following:data Pot = Pot [Prop] deriving (Eq, Show, Typeable)data BaseTableState = BaseTableState [Prop] deriving (Eq, Show, Typeable)instance Packet Pot where    unstuff xs = case props                 of Just props - (Just $ Pot props, xs')                    Nothing - (Nothing, xs)        where (props, xs') = unstuffprops xs potProps  this is the only difference    stuff (Pot a) = stuffprops a    size (Pot a) = sizeprops ainstance Convertible [Prop] Pot where    convert_AB a = Pot $ mergeprops a potProps    convert_BA (Pot b) = binstance Packet BaseTableState where    unstuff xs = case props                 of Just props - (Just $ BaseTableState props, xs')                    Nothing - (Nothing, xs)        where (props, xs') = unstuffprops xs baseTableStateProps    stuff (BaseTableState a) = stuffprops a    size (BaseTableState a) = sizeprops ainstance Convertible [Prop] BaseTableState where    convert_AB a = BaseTableState $ mergeprops a baseTableStateProps    convert_BA (BaseTableState b) = bNotice that the differences are only in the list of properties required for conversion. I'm wondering if this can be simplified somehow.You could consider creating a monad for the "unstuff" part of the operation that would hide dealing with the FastString, the tupling and the case analysis on Maybe.Your code might then look like:class (Eq a) = Packet a where   unstuff :: Unstuff a   stuff :: a - P.FastString   size :: a - Intinstance Packet BaseTableState where  unstuff = unstuffprops baseTableStateProps = return . BaseTableState  sutff (BaseTableState a) = stuffprops a  size (BaseTableState a) = sizeprops a where Unstuff is the type constructor for your monad.If you end up doing a lot of instances like this, the monad could well be a win;  it also gives you the opportunity to add error reporting during the parse if you want.As a side note, I see you are doing a bunch of operations on lists of properties.  If performance is an issue, you might want to consider using Data.Map or similar.  If your properties lists can get big, mergeprops looks like a potential problem (   O( n*(n+m) ) each time it's called   ).___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Haskell scripting system (please help me simplify the design)

2005-10-27 Thread Joel Reymont

Robert,

On Oct 27, 2005, at 4:59 PM, Robert Dockins wrote:

You could consider creating a monad for the unstuff part of the  
operation that would hide dealing with the FastString, the tupling  
and the case analysis on Maybe.


Could you elaborate on this a bit please? How would I write and use  
such a monad?


If you end up doing a lot of instances like this, the monad could  
well be a win;  it also gives you the opportunity to add error  
reporting during the parse if you want.


This is exactly the problem I'm facing now. Parsing is failing and I  
need to take apart my pure code just for testing. How would you code  
this monad?


As a side note, I see you are doing a bunch of operations on lists  
of properties.  If performance is an issue, you might want to  
consider using Data.Map or similar.  If your properties lists can  
get big, mergeprops looks like a potential problem (   O( n*(n+m) )  
each time it's called   ).


What would I use as the key for each map entry? If I knew this then I  
could use a map :-). As it stands, each property is a solid chunk and  
I can't even extract the name of the attribute it was created with. I  
don't think Map lets me index on Strings, does it?


Since I end up modifying properties a lot I think I sould use monads  
but I need to read up to get a clear picture.


Joel

--
http://wagerlabs.com/





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


Re: [Haskell-cafe] Haskell scripting system (please help me simplify the design)

2005-10-27 Thread Joel Reymont
Something else just occurred to me... How would I represent no  
command using the Unstuff monad? I'm returning Maybe Command right  
now, would this change?


On Oct 27, 2005, at 4:59 PM, Robert Dockins wrote:

You could consider creating a monad for the unstuff part of the  
operation that would hide dealing with the FastString, the tupling  
and the case analysis on Maybe.


Your code might then look like:

class (Eq a) = Packet a where
   unstuff :: Unstuff a
   stuff :: a - P.FastString
   size :: a - Int

instance Packet BaseTableState where
  unstuff = unstuffprops baseTableStateProps = return .  
BaseTableState

  sutff (BaseTableState a) = stuffprops a
  size (BaseTableState a) = sizeprops a


where Unstuff is the type constructor for your monad.


--
http://wagerlabs.com/





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


Re: [Haskell-cafe] Haskell scripting system (please help me simplify the design)

2005-10-27 Thread Cale Gibbard
On 27/10/05, Joel Reymont [EMAIL PROTECTED] wrote:
 On Oct 27, 2005, at 4:59 PM, Robert Dockins wrote:
[snip]
  As a side note, I see you are doing a bunch of operations on lists
  of properties.  If performance is an issue, you might want to
  consider using Data.Map or similar.  If your properties lists can
  get big, mergeprops looks like a potential problem (   O( n*(n+m) )
  each time it's called   ).

 What would I use as the key for each map entry? If I knew this then I
 could use a map :-). As it stands, each property is a solid chunk and
 I can't even extract the name of the attribute it was created with. I
 don't think Map lets me index on Strings, does it?
[snip]
  Joel


You can use any type in Ord as an index for a Map -- see fromList in
the Data.Map documentation. Strings are actually quite an effective
type of key, as they don't usually even need to be fully evaluated to
be compared.
 - Cale
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Please help me

2003-06-04 Thread David Savimbi
From: David Jonas Savimbi
Johannesburg, South Africa
Email: [EMAIL PROTECTED]
June 3rd, 2003.

Dear Sir,
It is my humble pleasure to write you this letter irrespective of the fact that you do 
not know me. However, I got your name through your country business directory here in 
my search for a reliable and trustworthy person that can assist me confidently.
My name is Mr.John Jonas Savimbi. I am the son of Late Dr. Jonas Savimbi from Angola. 
I am 29 years old and I have got two younger sisters of same blood. Our mother died 
almost a year ago. We are all fighting for political asylum in South Africa. We cannot 
find a home in Angola anymore because of the war that our late father fought with the 
government of Angola until he died in that war. The government of Angola is now mad at 
us because our late father also wanted to be president and caused the people to fight 
the war for him because he was the president of UNITA political movement of Angola.
So now we are in South Africa and we are suffering too much because we don't have 
money and the government of South Africa will not give jobs to asylum seekers. I am 
much concerned about my younger sisters who are finding it very difficult to manage in 
the situation. But I know that we should not suffer this way. I know that I must not 
let my younger sisters get into trouble because of money. So after consideration I am 
hereby begging for your assistance to help me to recover the sum of USD $29 Million 
which is my inheritance from my late mother. My late mother had taken this money with 
her to Spain in a diplomatic metal box marked (Precious Stones). Subsequently she 
lodged the metal box (As precious Stones) with a Securities and Valuables Protection 
company in Spain. I am supposed to be the beneficiary in the event of her death. 
However, all effort I made to go Spain to claim was refused by the Spainish embassy. 
And this was while it was still possible for me to travel. Now I cannot travel 
anywhere anymore. So in the situation that we are facing now, I must find somebody who 
can go to the Spain on my behalf.
I understand that I will have to transfer my beneficiary rights unto you. I am willing 
to do so in the hope that you are a God fearing person who will not abandon us after 
you have the money. So from the bottom of my heart I am giving you 20% of the all the 
money. Once we have enough to sustain us sufficiently, you may be come our fund 
manager and invest the rest wisely for us. If you will be kind to assist us, please 
inform me urgently.
Kind regards to you and your family.
Sincerely,

David Jonas savimbi


___
Haskell-Cafe mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: please help me

2002-04-06 Thread Michal Wallace

On Sun, 7 Apr 2002, Eric wrote:

| Hi there, I am a beginner a haskell,and I have some
| difficulty in dealing with an assignment that is to
| translate a string representation of a list of
| appointments into a list of appointments.  For example:

[requirements snipped] 

| How can I finish the requirement make use of library
| functions such as words, unwords, lines and break.

Hey Leo,

Well, I'm just learning haskell too, but I decided to give
this a shot. I think I solved the main problem, but I did
hit a few snags of my own so I can't be sure. Here goes:

Basically, I defined appointment as a single type...  But
I couldn't figure out how to print that type. So I can't
really test what I've done, other than I know it
compiles. :) Can someone show me how to fill in show down
here? )

 module Main where
 
 data Appt = Appt (Bool, Int, Int, String)
 instance Show Appt where
show x = ???


I then used liness and words to break the multi-line string
into a list of lists of words:

 strToApps :: String - [Appt]
 strToApps x = map lineToApp (lines x)
 lineToApp x = wordsToApp (words x)


Since the starting ! was optional, the structure of the
list could go in two directions here:

 wordsToApp :: [String] - Appt
 wordsToApp ws | head ws == ! = mkAppt True (tail ws)
   | otherwise  = mkAppt False (ws)


Now it's just a matter of parsing the rest of the line.  For
simplicity's sake, I took the liberty of assuming you always
used the same number of digits for the hours, so I didn't
have to search for the -:

 mkAppt :: Bool - [String] - Appt
 mkAppt isImp (w:ws) = Appt (isImp, start, done, note)
 where (hs, hd) = splitAt 3 w  -- assumes zero-padded (eg 01-03)
   start = atoi hs
   done = atoi hd
   note = foldr1 concat ws
   concat a b = a ++   ++ b



That atoi function came from working through the exercises
in Rex Pages online book ( http://www.cs.ou.edu/cs1323h/textbook/haskell.shtml )

 horner str = foldr1 op (reverse str)
 where op d s = d + (10 * s)
 atoi str = horner [digitToInt d | d - str]


Then I defined a main function:

 -- I wonder what a refec is. :)
 main = do print $ strToApps ! 10-11 lecture\n12-13 lunch at the refec :(


... And that's it! I think it would work if I could figure
out how to print Appt objects (or whatever you call them in
haskell). Meanwhile, I get this because of the way I defined
show:

Main main
[???,???]

Cheers,

- Michal   http://www.sabren.net/   [EMAIL PROTECTED] 

Give your ideas the perfect home: http://www.cornerhost.com/
 cvs - weblogs - php - linux shell - perl/python/cgi - java


___
Haskell-Cafe mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/haskell-cafe



Re: Please help me

2001-02-08 Thread Ashley Yakeley

At 2001-02-08 13:49, FAIZAN RAZA wrote:

write a Haskell
function cartesianProduct which when given three lists  (to represent three
sets) of integers returns a list of lists of ordered triples.

That's easy. Just define 'product' as a function that finds the cartesian 
product of any number of lists, and then once you've done that you can 
apply it to make the special case of three items like this:

cartesianProduct a b c = product [a,b,c]

At least, that's how I would do it.

-- 
Ashley Yakeley, Seattle WA


___
Haskell-Cafe mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/haskell-cafe



Re: Please help me

2001-02-08 Thread Ashley Yakeley

At 2001-02-08 02:04, Ashley Yakeley wrote:

That's easy. Just define 'product' as a function that finds the cartesian 
product of any number of lists, and then once you've done that you can 
apply it to make the special case of three items like this:

cartesianProduct a b c = product [a,b,c]

At least, that's how I would do it.

eesh, 'product' is something else in the Prelude. Better call it 
'cartprod' or something.

-- 
Ashley Yakeley, Seattle WA


___
Haskell-Cafe mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/haskell-cafe



RE: Please help me

2001-02-08 Thread Chris Angus

Faizan,

A clue is to use list comprehensions (which are very like ZF set notation)

First think how you would define a cartesian product in set notation

X x Y x Z = {(x,y,z) | ...}

and then think how this is written in list comprehension notation

Chris

 -Original Message-
 From: FAIZAN RAZA [mailto:[EMAIL PROTECTED]]
 Sent: 08 February 2001 13:49
 To: [EMAIL PROTECTED]
 Subject: Please help me
 
 
 Hello
 
 
 Please help me to solve this questions
 
 
 Question
 
 Cartesian Product of three sets, written as X x Y x Z is 
 defined as the set
 of all ordered triples such that the first element is a 
 member of X, the
 second is member of Y, and the thrid member of set Z. write a Haskell
 function cartesianProduct which when given three lists  (to 
 represent three
 sets) of integers returns a list of lists of ordered triples.
 
 For examples,  cartesianProduct [1,3][2,4][5,6] returns
 [[1,2,5],[1,2,6],[1,4,5],[1,4,6],[3,2,5],[3,2,6],[3,4,5],[3,4,6]]
 
 
 
 Please send me reply as soon as possible
 
 Ok
 
 I wish you all the best of luck
 
 
 
 ___
 Haskell-Cafe mailing list
 [EMAIL PROTECTED]
 http://www.haskell.org/mailman/listinfo/haskell-cafe
 

___
Haskell-Cafe mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/haskell-cafe