[Haskell-cafe] IterIO: How to write use my inumReverse

2011-07-04 Thread John Ky
Hi Haskell Cafe,

I've defined the following reverse echo server that echos text back in
reverse:

module Programs.TcpEchoIterServer where

import Control.Concurrent
import Control.Exception
import Control.Monad
import Control.Monad.Trans
import Data.IterIO
import Data.IterIO.Inum
import Network
import System.IO
import System.IO.Error (isEOFError)
import qualified Data.ByteString.Lazy as L
import qualified Data.ByteString.Lazy.Char8 as C

iterHandle' :: (MonadIO m) = Handle - IO (Iter L.ByteString m (), Onum
L.ByteString m a)
iterHandle' = iterHandle

main = withSocketsDo $ do
  sListen - listenOn (PortNumber 8000)
  putStrLn Listening on Port 8000
  forkIO $ forever $ do
(sSession, hostname, port) - accept sListen
hSetBuffering sSession NoBuffering
putStrLn (Connected to  ++ hostname ++ : ++ show port)
forkIO $ do
  (iter, enum) - iterHandle' sSession
  enum |$ inumLines .| inumReverse .| inumUnlines .| iter
  putStrLn Press CTRL-D to quit.
  exitOnCtrlD

iterLines :: (Monad m) = Iter L.ByteString m [L.ByteString]
iterLines = do
  line - lineI
  return [line]

iterUnlines :: (Monad m) = Iter [L.ByteString] m L.ByteString
iterUnlines = (L.concat . (++ [C.pack \n])) `liftM` dataI

iterReverse :: (Monad m) = Iter [L.ByteString] m [L.ByteString]
iterReverse = do
  lines - dataI
  return (map L.reverse lines)

inumLines = mkInum iterLines
inumUnlines = mkInum iterUnlines
inumReverse = mkInum iterReverse

exitOnCtrlD = try getLine = either
  (\e - unless (isEOFError e) $ ioError e)
  (const exitOnCtrlD)


It all works fine.

My question is: Is it possible to rewrite inumReverse to be this:

iterReverse :: (Monad m) = Iter L.ByteString m L.ByteString
iterReverse = do
  line - dataI
  return (L.reverse line)

inumReverse = mkInum iterReverse


And still be able to use it in the line:

enum |$ inumLines .| {-- inumReverse goes in here somehow --} .| inumUnlines
.| iter


The reason I ask is that the Haskell function reverse has the type [a] -
[a], not  [[a]] - [[a]].

I thought perhaps the alternative inumReverse is cleaner than the original
as it behaves more similarly to Haskell's own reverse function.

Cheers,

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


Re: [Haskell-cafe] Confused about my IterIO code

2011-07-03 Thread John Ky
Thanks David,

Right - it invokes its iter repeatedly because mkInumC does that and mkInum is
defined as:

mkInum = mkInumC id noCtl


So to do it all manually is:

inumReverseLines :: (Monad m) = Inum L.ByteString L.ByteString m a
inumReverseLines = mkInumM $ loop where
  loop = do
eof - atEOFI
unless eof $ do
  line - lineI
  ifeed (L.concat [L.reverse line, C.pack \n])
  loop


Cheers,

-John

On 1 July 2011 01:20, dm-list-haskell-c...@scs.stanford.edu wrote:

 At Thu, 30 Jun 2011 23:53:02 +1000,
 John Ky wrote:
 
  But all I've done is:
 
  enum |$ inumReverseLines .| iter
 
  inumReverseLines = mkInum $ do
line - lineI
return (L.reverse (L.concat [line, C.pack \n]))

 mkInum repeatedly invokes its iter argument so as to keep producing
 chunks.  If you want to reverse only one line, it might be easiest to
 use something along the lines of:

mkInumM $ do
  line - lineI
  ifeed (L.reverse (L.concat [line, C.pack \n]))

 mkInumM is a more manual Inum construction function that doesn't
 automatically do things like loop or handle EOF conditions.

 David

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


[Haskell-cafe] Confused about my IterIO code

2011-06-30 Thread John Ky
Hi Hakell Cafe,

I'm struggling to understand my unambitious IterIO code that somehow manages
to work.

Basically I run an echo server that is supposed to read from a socket line
by line and write back to the socket with all the characters in the line
reversed:

import Control.Exception
import Control.Monad
import Control.Monad.Trans
import Data.IterIO
import Data.IterIO.Inum
import Network
import System.IO
import System.IO.Error (isEOFError)
import qualified Data.ByteString.Lazy as L
import qualified Data.ByteString.Lazy.Char8 as C

iterHandle' :: (MonadIO m) = Handle - IO (Iter L.ByteString m (), Onum
L.ByteString m a)
iterHandle' = iterHandle

main = withSocketsDo $ do
  sListen - listenOn (PortNumber 8000)
  putStrLn Listening on Port 8000
  forkIO $ forever $ do
(sSession, hostname, port) - accept sListen
hSetBuffering sSession NoBuffering
putStrLn (Connected to  ++ hostname ++ : ++ show port)
forkIO $ do
  (iter, enum) - iterHandle' sSession
  enum |$ inumReverseLines .| iter
  putStrLn Press CTRL-D to quit.
  exitOnCtrlD

inumReverseLines :: (Monad m) = Inum L.ByteString L.ByteString m a
inumReverseLines = mkInum $ do
  line - lineI
  return (L.reverse (L.concat [line, C.pack \n]))

exitOnCtrlD = try getLine = either
  (\e - unless (isEOFError e) $ ioError e)
  (const exitOnCtrlD)


When I run it, it does this:

asdfghc7@hoggy-nn:/home/hoggy$ nc localhost 8000
1234
4321
4321
1234
abcde
edcba


The red lines are the replies from my echo server.

But all I've done is:

enum |$ inumReverseLines .| iter

inumReverseLines = mkInum $ do
  line - lineI
  return (L.reverse (L.concat [line, C.pack \n]))


No attempt was made to reverse more than one line - at least as far as I can
see.  What have I done wrong that it should work so well?

Also, is there a better way to do this?

Cheers,

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


Re: [Haskell-cafe] IterIO type restricted functions

2011-06-29 Thread John Ky
Hi David,

Good point.  Not too fussed, though now that I think about it, I would have
preferred it if enumFile' was defined in the tutorial rather than in the
module.

Cheers,

-John

On 29 June 2011 13:53, dm-list-haskell-c...@scs.stanford.edu wrote:

 At Wed, 29 Jun 2011 10:11:26 +1000,
 John Ky wrote:
 
  [1  multipart/alternative (7bit)]
  [1.1  text/plain; ISO-8859-1 (7bit)]
 
  Hi all,
 
  From the IterIO tutorial:
 
  enumFile' is like enumFile above, but type restricted to data in the
 lazy
  ByteString format, which is more efficient than plain Strings.
 (enumFile
  supports multiple types, but in this example there is not enough
  information for Haskell to choose one of them, so we must use
 enumfile' or
  use :: to specify a type explicitly.
 
  Which is fine, but shouldn't there also be iterHandle' and iterStream'?
 
  Also I'm guessing the f is a typo that should be F.

 Thanks, just fixed the typo in git.

 I guess the logic is that these are super-easy to define in your own
 code, so better not to pollute the namespace with lots of symbols.

 The same logic also applies to enumFile'.  However, in testing I found
 that I often wanted something like enumFile' to prototype something
 quick and dirty, just to test from a file.  So I added it as a
 convenience to myself.

 I don't have very strong feelings either way.  If enumFile' is
 inconsistent, my inclination would be to get rid of enumFile' rather
 than add iterHandle' etc.  That way, if someone wants to do everything
 in terms of strict byte strings, or text, or whatever, then can just
 define the primed versions to be whatever data format they prefer.

 I guess the reason it doesn't feel to horrible as-is is that enumFile
 is already a convenience function effectively combining openFile with
 enumHandle.

 David

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


[Haskell-cafe] How to flush with IterIO in echo server

2011-06-29 Thread John Ky
Hi Haskell Cafe,

I've written an echo server using just sockets:

import Control.Concurrent
import Control.Exception
import Control.Monad
import Network
import Offsync.Data
import System.IO
import System.IO.Error (isEOFError)

main = withSocketsDo $ do
  sListen - listenOn (PortNumber 8000)
  putStrLn Listening on Port 8000
  forkIO $ forever $ do
(sSession, hostname, port) - accept sListen
putStrLn (Connected to  ++ hostname ++ : ++ show port)
forkIO $ echoLines sSession
  putStrLn Press CTRL-D to quit.
  exitOnCtrlD

echoLines h = try (hGetLine h) = either
  (\e - do { hClose h; if isEOFError e then print e else ioError e})
  (\l - do { hPutStrLn h l; hFlush h; echoLines h})

exitOnCtrlD = try getLine = either
  (\e - unless (isEOFError e) $ ioError e)
  (const exitOnCtrlD)


When I send text to it, it will echo it back immediately after my newline.

I then modified it to user IterIO:

import Control.Concurrent
import Control.Exception
import Control.Monad
import Control.Monad.Trans
import Data.IterIO
import Data.IterIO.Inum
import Network
import System.IO
import System.IO.Error (isEOFError)
import qualified Data.ByteString.Lazy as L

iterHandle' :: (MonadIO m) = Handle - IO (Iter L.ByteString m (), Onum
L.ByteString m a)
iterHandle' = iterHandle

main = withSocketsDo $ do
  sListen - listenOn (PortNumber 8000)
  putStrLn Listening on Port 8000
  forkIO $ forever $ do
(sSession, hostname, port) - accept sListen
putStrLn (Connected to  ++ hostname ++ : ++ show port)
forkIO $ do
  (iter, enum) - iterHandle' sSession
  enum |$ iter
  return ()
  putStrLn Press CTRL-D to quit.
  exitOnCtrlD

exitOnCtrlD = try getLine = either
  (\e - unless (isEOFError e) $ ioError e)
  (const exitOnCtrlD)


It works, however it doesn't send anything back to me until end of file.

I fixed that problem with my sockets version by flushing after each line,
but I don't know if IterIO will let me flush on every newline.

Any ideas?

Cheers,

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


[Haskell-cafe] Cleaner way to write code and handle errors?

2011-06-28 Thread John Ky
Hi all,

I'm practising my Haskell by writing a simple TCP echo server and finding
that getting my program control to be succinct is rather tricky.  In
particular, I have return () everywhere, my error handling is verbose and
I'm not entirely sure my recursion is the cleanest way syntactically to get
my loops going and terminating.

I must be doing something obviously un-Haskell-like.

Any suggestions on how I can improve my code?  Code below.

Cheers,

-John

import Control.Concurrent
import Control.Exception
import Control.Monad
import Network
import System.IO
import System.IO.Error (isEOFError)

main = withSocketsDo $ do
  sListen - listenOn (PortNumber 8000)
  putStrLn Listening on Port 8000
  forkIO $ forever $ do
(sSession, hostname, port) - accept sListen
putStrLn (Connected to  ++ hostname ++ : ++ (show port))
let processLine = forkIO $ do
lineResult - try (hGetLine sSession)
case lineResult of
  Right line - do
putStrLn line
processLine
return ()
  Left e -
if isEOFError e
then putStrLn (show e)
else do
  ioError e
  return ()
return ()
processLine
return()
  line - getLine
  return ()
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Cleaner way to write code and handle errors?

2011-06-28 Thread John Ky
Hi Eric, Ivan,

On 28 June 2011 18:32, Erik de Castro Lopo mle...@mega-nerd.com wrote:

 The hlint program would have flagged both of those and possibly
 others. See:


Cool!

It didn't flag either for me, but it recommended replacing ++ (show
port)with ++
show port, if then else with unless, putStrLn (show x) with print x, and do
stuff with stuff.

All useful to know.

On 28 June 2011 18:16, Ivan Lazar Miljenovic ivan.miljeno...@gmail.com
 wrote:

 I don't think you need all those return () everywhere...


You're right.  At some point I added it in to (try to) make the compiler
happy, but it must have been or become unnecessary.

I still need two though because forkIO (and therefore my processLine function)
returns IO ThreadId, but the last line for do notation must be return
()(see below).

On 28 June 2011 18:16, Ivan Lazar Miljenovic ivan.miljeno...@gmail.com
 wrote:

 And at the end, why do you do line - getLine when you don't use the
 result?


Oh that.  I was trying to figure out a way to terminate by program.  I've
now changed it to exit on EOF.

Here is my second attempt.  Is it much better?:

import Control.Concurrent
import Control.Exception
import Control.Monad
import Network
import System.IO
import System.IO.Error (isEOFError)

main = withSocketsDo $ do
  sListen - listenOn (PortNumber 8000)
  putStrLn Listening on Port 8000
  forkIO $ forever $ do
(sSession, hostname, port) - accept sListen
putStrLn (Connected to  ++ hostname ++ : ++ show port)
let processLine = forkIO $ do
lineResult - try (hGetLine sSession)
case lineResult of
  Right line - do
putStrLn line
processLine
return ()
  Left e - if isEOFError e
then print e
else ioError e
processLine
return()
  putStrLn Press CTRL-D to quit.
  let processStdIn = do
  lineResult - try getLine
  case lineResult of
Right line - processStdIn
Left e - unless (isEOFError e) $ ioError e
  processStdIn


Thanks for the suggestions.

Cheers,

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


Re: [Haskell-cafe] Cleaner way to write code and handle errors?

2011-06-28 Thread John Ky
Thanks Jonas,

I feel much better already:

import Control.Concurrent
import Control.Exception
import Control.Monad
import Network
import System.IO
import System.IO.Error (isEOFError)


main = withSocketsDo $ do
  sListen - listenOn (PortNumber 8000)
  putStrLn Listening on Port 8000
  forkIO $ forever $ do
(sSession, hostname, port) - accept sListen
putStrLn (Connected to  ++ hostname ++ : ++ show port)
forkIO $ echoLines sSession
  putStrLn Press CTRL-D to quit.
  exitOnEof

echoLines h = try (hGetLine h) = either
  (\e - if isEOFError e then print e else ioError e)
  (putStrLn = const (echoLines h))

exitOnEof = try getLine = either
  (\e - unless (isEOFError e) $ ioError e)
  (const exitOnEof)


I also worked out I didn't void by making processLines (now echoLines h) be
forkIO's argument rather than forkIO's result.

Cheers,

-John

2011/6/28 Jonas Almström Duregård jonas.dureg...@chalmers.se

 There is the void function in Control.Monad:

 http://hackage.haskell.org/packages/archive/base/latest/doc/html/Control-Monad.html#v:void

 Instead of using return () you can just use void processLine.

 Also some people like to use the either function instead of matching on
 Left/Right. In this case you can also avoid introducing a few names:

let processLine = void $ forkIO $
  try (hGetLine sSession) = either
 (\e - if isEOFError e
  then print e
  else ioError e)
(putStrLn = const processLine)


 On 28 June 2011 12:58, John Ky newho...@gmail.com wrote:
  Hi Eric, Ivan,
  On 28 June 2011 18:32, Erik de Castro Lopo mle...@mega-nerd.com wrote:
 
  The hlint program would have flagged both of those and possibly
  others. See:
 
  Cool!
  It didn't flag either for me, but it recommended replacing ++ (show port)
  with ++ show port, if then else with unless, putStrLn (show x) with print
 x,
  and do stuff with stuff.
  All useful to know.
  On 28 June 2011 18:16, Ivan Lazar
  Miljenovic ivan.miljeno...@gmail.com wrote:
 
  I don't think you need all those return () everywhere...
 
 
  You're right.  At some point I added it in to (try to) make the compiler
  happy, but it must have been or become unnecessary.
  I still need two though because forkIO (and therefore my processLine
  function) returns IO ThreadId, but the last line for do notation must be
  return () (see below).
  On 28 June 2011 18:16, Ivan Lazar
  Miljenovic ivan.miljeno...@gmail.com wrote:
 
  And at the end, why do you do line - getLine when you don't use the
  result?
 
  Oh that.  I was trying to figure out a way to terminate by program.  I've
  now changed it to exit on EOF.
  Here is my second attempt.  Is it much better?:
 
  import Control.Concurrent
  import Control.Exception
  import Control.Monad
  import Network
  import System.IO
  import System.IO.Error (isEOFError)
  main = withSocketsDo $ do
sListen - listenOn (PortNumber 8000)
putStrLn Listening on Port 8000
forkIO $ forever $ do
  (sSession, hostname, port) - accept sListen
  putStrLn (Connected to  ++ hostname ++ : ++ show port)
  let processLine = forkIO $ do
  lineResult - try (hGetLine sSession)
  case lineResult of
Right line - do
  putStrLn line
  processLine
  return ()
Left e - if isEOFError e
  then print e
  else ioError e
  processLine
  return()
putStrLn Press CTRL-D to quit.
let processStdIn = do
lineResult - try getLine
case lineResult of
  Right line - processStdIn
  Left e - unless (isEOFError e) $ ioError e
processStdIn
 
  Thanks for the suggestions.
  Cheers,
  -John
 
  ___
  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] IterIO type restricted functions

2011-06-28 Thread John Ky
Hi all,

From the IterIO tutorial:

enumFile' is like enumFile above, but type restricted to data in the
lazy ByteString
format, which is more efficient than plain Strings. (enumFile supports
multiple types, but in this example there is not enough information for
Haskell to choose one of them, so we must use enum*f*ile' or use :: to
specify a type explicitly.


Which is fine, but shouldn't there also be iterHandle' and iterStream'?

Also I'm guessing the *f* is a typo that should be *F*.

Cheers,

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


Re: [Haskell-cafe] Getting library documentation for installed packages on Windows

2011-06-22 Thread John Ky
Thanks Jack,

I can get the documentation okay with:

cabal install --reinstall *package-name*


Now I'm getting into another problem.

I specifically wanted the documentation for the Network module as its
documentation is not included in the default Haskell Platform install.

I run:

cabal install --reinstall *network*


But get the error shown in this ticket:
http://trac.haskell.org/network/ticket/39

I believe the network package is already installed, and I only want the
documentation for it.

What should I do?

Cheers,

-John

On 22 June 2011 11:14, Jack Henahan jhena...@uvm.edu wrote:

 John,

 Run `ghci`, then

:m System.Directory
getAppUserDataDirectory cabal

 That'll show you the directory where your cabal config is.

 On Jun 21, 2011, at 9:03 PM, John Ky wrote:

  Hi Svein,
 
  Where can I find this file on Windows 7 or Windows generally if its all
 the same?
 
  Cheers,
 
  -John
 
  On 22 June 2011 10:15, Svein Ove Aas sve...@gmail.com wrote:
  Yes, cabal does this if you have haddock installed.
 
  You'll probably have to edit .cabal/config, though. The relevant options
 should be fairly obvious in there.
 
  On Jun 22, 2011 12:52 AM, John Ky newho...@gmail.com wrote:
   Hi all,
  
   Lately I've been finding the Network module missing from the docs I
 download
   from the GHC website, which brings me to the question:
  
   Is there any way I could generate libraries for this, the core
 libraries and
   all installed cabal packages into one reference so I can work offline?
  
   Cheers,
  
   -John
 
  ___
  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] Getting library documentation for installed packages on Windows

2011-06-21 Thread John Ky
Hi all,

Lately I've been finding the Network module missing from the docs I download
from the GHC website, which brings me to the question:

Is there any way I could generate libraries for this, the core libraries and
all installed cabal packages into one reference so I can work offline?

Cheers,

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


Re: [Haskell-cafe] Getting library documentation for installed packages on Windows

2011-06-21 Thread John Ky
Hi Svein,

Where can I find this file on Windows 7 or Windows generally if its all the
same?

Cheers,

-John

On 22 June 2011 10:15, Svein Ove Aas sve...@gmail.com wrote:

 Yes, cabal does this if you have haddock installed.

 You'll probably have to edit .cabal/config, though. The relevant options
 should be fairly obvious in there.
 On Jun 22, 2011 12:52 AM, John Ky newho...@gmail.com wrote:
  Hi all,
 
  Lately I've been finding the Network module missing from the docs I
 download
  from the GHC website, which brings me to the question:
 
  Is there any way I could generate libraries for this, the core libraries
 and
  all installed cabal packages into one reference so I can work offline?
 
  Cheers,
 
  -John

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


Re: [Haskell-cafe] What's the advantage of writing Haskell this way?

2011-05-31 Thread John Ky
Thanks Malcom.

I suspected that much, so I added it:

data Stream m a
= Chunks (m a)
| EOF
deriving (Show, Eq)

instance (Monad m, MonadPlus m, Monoid (m a)) = Monoid (Stream m a) where
mempty = Chunks mempty
mappend (Chunks xs) (Chunks ys) = Chunks (xs `mappend` ys)
mappend _ _ = EOF

instance (Monad m, MonadPlus m) = Monad (Stream m) where
return = Chunks . return
Chunks xs = f = mconcat (fmap f xs)
EOF = _ = EOF

This gives me the error:

Iteratee.hs:30:10:
Non type-variable argument in the constraint: Monoid (m a)
(Use -XFlexibleContexts to permit this)
In the context: (Monad m, MonadPlus m, Monoid (m a))
While checking the context of an instance declaration
In the instance declaration for `Monoid (Stream m a)'

So I run with the new flag:

ghci -XFlexibleContexts Iteratee.hs

Then I get the following error instead:

Iteratee.hs:37:43:
Could not deduce (m ~ [])
from the context (Monad m, MonadPlus m)
  bound by the instance declaration at Iteratee.hs:35:10-51
  `m' is a rigid type variable bound by
  the instance declaration at Iteratee.hs:35:17
Expected type: [a]
  Actual type: m a
In the second argument of `fmap', namely `xs'
In the first argument of `mconcat', namely `(fmap f xs)'
In the expression: mconcat (fmap f xs)

Which is complaining about the line I highlighted above.  So I try:

data Stream m a
= Chunks (m a)
| EOF
deriving (Show, Eq)

instance (Monad m, MonadPlus m, Monoid (m a)) = Monoid (Stream m a) where
mempty = Chunks mempty
mappend (Chunks xs) (Chunks ys) = Chunks (xs `mappend` ys)
mappend _ _ = EOF

instance (Monad m, MonadPlus m, Monoid (m a)) = Monad (Stream m) where
return = Chunks . return
Chunks xs = f = mconcat (fmap f xs)
EOF = _ = EOF

But the same trick doesn't work:

Iteratee.hs:35:10:
Variable occurs more often in a constraint than in the instance head
  in the constraint: Monoid (m a)
(Use -XUndecidableInstances to permit this)
In the instance declaration for `Monad (Stream m)'

Is that because I don't use a on the right hand side of =?

Cheers,

-John

On 31 May 2011 15:54, Malcolm Wallace malcolm.wall...@me.com wrote:


 instance (Monad m, MonadPlus m) = Monoid (Stream m a) where

  mempty = Chunks mempty
 mappend (Chunks xs) (Chunks ys) = Chunks (xs `mappend` ys)
  mappend _ _ = EOF


 Iteratee.hs:28:25:
 No instance for (Monoid (m a))
   arising from a use of `mempty'


 There is a clue in the first part of the error message.  Add the required
 instance as part of the predicate:

 instance (Monad m, MonadPlus m, Monoid (m a)) = Monoid (Stream m a) where
 ...

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


[Haskell-cafe] What's the advantage of writing Haskell this way?

2011-05-30 Thread John Ky
Hi all,

I'm trying to learn about enumerators by reading this
paperhttps://john-millikin.com/downloads/enumerator_0.4.10.pdfand
came across some code on page 2 that I found hard to digest, but I
think
I finally got it:

import Data.Monoid

data Stream a
= Chunks [a]
| EOF
deriving (Show, Eq)

instance Monad Stream where
return = Chunks . return
Chunks xs = f = mconcat (fmap f xs)
EOF = _ = EOF

instance Monoid (Stream a) where
mempty = Chunks mempty
mappend (Chunks xs) (Chunks ys) = Chunks (xs ++ ys)
mappend _ _ = EOF


I guess, it shows my lack of experience in Haskell, but my question is, why
is writing the code this way preferred over say writing it like this:

import Data.Monoid

data Stream a
= Chunks [a]
| EOF
deriving (Show, Eq)

instance Monad Stream where
return x = Chunks [x]
Chunks xs = f = mconcat (fmap f xs)
EOF = _ = EOF

instance Monoid (Stream a) where
mempty = Chunks []
mappend (Chunks xs) (Chunks ys) = Chunks (xs ++ ys)
mappend _ _ = EOF


Cheers,

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


Re: [Haskell-cafe] What's the advantage of writing Haskell this way?

2011-05-30 Thread John Ky
Hi Brandon,

Thanks for your suggestion.  I'm a little stuck as adding Monad and
MonadPlus in my instance declaration doesn't seem sufficient.  I know
mconcat comes from Monoid, but I don't know how to put that in.

data Stream m a
= Chunks (m a)
| EOF
deriving (Show, Eq)

instance (Monad m, MonadPlus m) = Monoid (Stream m a) where
mempty = Chunks mempty
mappend (Chunks xs) (Chunks ys) = Chunks (xs `mappend` ys)
mappend _ _ = EOF

instance (Monad m, MonadPlus m) = Monad (Stream m) where
return = Chunks . return
Chunks xs = f = mconcat (fmap f xs)
EOF = _ = EOF

Iteratee.hs:28:25:
No instance for (Monoid (m a))
  arising from a use of `mempty'
Possible fix: add an instance declaration for (Monoid (m a))
In the first argument of `Chunks', namely `mempty'
In the expression: Chunks mempty
In an equation for `mempty': mempty = Chunks mempty

Iteratee.hs:29:54:
No instance for (Monoid (m a))
  arising from a use of `mappend'
Possible fix: add an instance declaration for (Monoid (m a))
In the first argument of `Chunks', namely `(xs `mappend` ys)'
In the expression: Chunks (xs `mappend` ys)
In an equation for `mappend':
mappend (Chunks xs) (Chunks ys) = Chunks (xs `mappend` ys)

Iteratee.hs:34:43:
Could not deduce (m ~ [])
from the context (Monad m, MonadPlus m)
  bound by the instance declaration at Iteratee.hs:32:10-51
  `m' is a rigid type variable bound by
  the instance declaration at Iteratee.hs:32:17
Expected type: [a]
  Actual type: m a
In the second argument of `fmap', namely `xs'
In the first argument of `mconcat', namely `(fmap f xs)'
In the expression: mconcat (fmap f xs)
Failed, modules loaded: none.

Cheers,

-John

On 31 May 2011 00:38, Brandon Moore brandon_m_mo...@yahoo.com wrote:

 From: John Ky newho...@gmail.com
 Sent: Monday, May 30, 2011 8:01 AM
 
 Hi all,
 
 I'm trying to learn about enumerators by reading this paper and came
 across some code on page 2 that I found hard to digest, but I think I
 finally got it:


 Hi John. These programs should behave identically, and I think your version
 should be preferred.
 This first code uses some class methods like mconcat, but it seems to
 always be used on
 the list in Chunks, so it will only ever use the definition for list, which
 is equivalent to what
 you wrote directly in the second code.

 The result may not be useful, but to understand this more thoroughly you
 might
 try parametrizating the definition of Stream so the use of more general
 operators
 actually means something. Perhaps

 data Stream m a =
   Chunks (m a)
   | EOF

 I think you would want Monad and MonadPlus on m.


 import Data.Monoid
 
 
 data Stream a
 = Chunks [a]
 | EOF
 deriving (Show, Eq)
 
 
 instance Monad Stream where
 return = Chunks . return
 Chunks xs = f = mconcat (fmap f xs)
 EOF = _ = EOF
 
 
 instance Monoid (Stream a) where
 mempty = Chunks mempty
 mappend (Chunks xs) (Chunks ys) = Chunks (xs ++ ys)
 mappend _ _ = EOF
 
 
 I guess, it shows my lack of experience in Haskell, but my question is,
 why is writing the code this way preferred over say writing it like this:
 
 
 import Data.Monoid
 
 
 data Stream a
 = Chunks [a]
 | EOF
 deriving (Show, Eq)
 
 
 instance Monad Stream where
 return x = Chunks [x]
 Chunks xs = f = mconcat (fmap f xs)
 EOF = _ = EOF
 
 
 instance Monoid (Stream a) where
 mempty = Chunks []
 mappend (Chunks xs) (Chunks ys) = Chunks (xs ++ ys)
 mappend _ _ = EOF
 
 
 Cheers,
 
 
 -John
 
 
 ___
 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] Circular pure data structures?

2009-07-14 Thread John Ky
Hello,

Is it possible to create a circular pure data structure in Haskell?  For
example:

a :: Data

let b = getNext a
let c = getNext b

c == a -- Gives True

Thanks,

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


Re: [Haskell-cafe] Circular pure data structures?

2009-07-14 Thread John Ky
Hello,

Actually, I wanted to be able to create a tree structure when I can navigate
both leaf-ward and root-ward.  I didn't actually care for equality.

I think the tying the knot technique as mentioned by others is sufficient
for this purpose.

Cheers,

-John

On Wed, Jul 15, 2009 at 8:55 AM, John Dorsey hask...@colquitt.org wrote:

 John,

  Is it possible to create a circular pure data structure in Haskell?  For
  example:

 Creating the data structure is easy; as other respondents have pointed out.
 A simple example is this...

 ones  = 1 : ones
 ones' = 1 : ones'

 Comparing these values is harder.  All of (ones), (ones'), (tail ones), and
 so forth are equal values.  But I don't know how to compare them.  My
 Spidey-sense tells me there's probably a simple proof that you can't, if
 you
 care about the comparison terminating.

 Pointer equality (ie. testing if the values are represented by the same
 bits in memory) is no good, since it's entirely up to the compiler whether
 ones and ones' use the same bits.  (They won't, but that's not important.)
 In general pointer equality of Haskell values, such as ones and (tail
 ones) interferes with referential transparency, which is held in high
 regard around here.  Although, for the record, when pointer equality is
 really what you want, I'm sure there's ways to Force It.

 For your purposes, does it matter if you can actually do the comparison?
  Is
 it enough to know that ones and (tail ones) are equal?

 Regards,
 John

 ___
 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] Circular pure data structures?

2009-07-14 Thread John Ky
Hello,

If I use zippers, do all my nodes need to be the same type?  My tree doesn't
have the same type for every node.  For example:

Modules - Module - Types - Type - Members - Member - Type - ...

Thanks

-John

On Wed, Jul 15, 2009 at 2:41 PM, Miguel Mitrofanov miguelim...@yandex.ruwrote:

 Sufficient, but not good.

 Try zippers instead.


 On 15 Jul 2009, at 08:29, John Ky wrote:

  Hello,

 Actually, I wanted to be able to create a tree structure when I can
 navigate both leaf-ward and root-ward.  I didn't actually care for equality.

 I think the tying the knot technique as mentioned by others is sufficient
 for this purpose.

 Cheers,

 -John

 On Wed, Jul 15, 2009 at 8:55 AM, John Dorsey hask...@colquitt.org
 wrote:
 John,

  Is it possible to create a circular pure data structure in Haskell?  For
  example:

 Creating the data structure is easy; as other respondents have pointed
 out.
 A simple example is this...

 ones  = 1 : ones
 ones' = 1 : ones'

 Comparing these values is harder.  All of (ones), (ones'), (tail ones),
 and
 so forth are equal values.  But I don't know how to compare them.  My
 Spidey-sense tells me there's probably a simple proof that you can't, if
 you
 care about the comparison terminating.

 Pointer equality (ie. testing if the values are represented by the same
 bits in memory) is no good, since it's entirely up to the compiler whether
 ones and ones' use the same bits.  (They won't, but that's not important.)
 In general pointer equality of Haskell values, such as ones and (tail
 ones) interferes with referential transparency, which is held in high
 regard around here.  Although, for the record, when pointer equality is
 really what you want, I'm sure there's ways to Force It.

 For your purposes, does it matter if you can actually do the comparison?
  Is
 it enough to know that ones and (tail ones) are equal?

 Regards,
 John

 ___
 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] Where can I get GHC for Solaris?

2009-07-08 Thread John Ky
Hi Aycan,

This is the version of make I am using:

j...@sun05:~ $ make -v
GNU Make 3.81
Copyright (C) 2006  Free Software Foundation, Inc.
This is free software; see the source for copying conditions.
There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A
PARTICULAR PURPOSE.

This program built for sparc-sun-solaris2.9
j...@sun05:~ $ uname -a
SunOS sun05 5.9 Generic_118558-30 sun4u sparc SUNW,Sun-Fire-280R

Thanks,

-John

On Wed, Jul 8, 2009 at 4:48 PM, Aycan iRiCAN aycan.iri...@core.gen.trwrote:

 Çar, 2009-07-08 tarihinde 09:55 +1000 saatinde, John Ky yazdı:
  Hi,
 
  I had a go with the binary dist, and got this error message on the
  make install:
 
  /home/a-m/joky/.tools/ghc-6.8.2/lib/ghc-6.8.2'
  -DPKG_DATADIR='/export/home/a-m/joky/.tools/ghc-6.8.2/share/ghc-6.8.2'
 package.conf.in \
  | grep -v '^#pragma GCC' \
  | sed -e 's///g' -e 's/:[   ]*,/: /g' \
 
  | /export/home/a-m/joky/ghc-6.8.2/utils/ghc-pkg/ghc-pkg.bin
  --global-conf
 /export/home/a-m/joky/.tools/ghc-6.8.2/lib/ghc-6.8.2/package.conf update -
 --force
  ld.so.1: ghc-pkg.bin: fatal: libm.so.2: version `SUNW_1.2' not found
  (required by
  file /export/home/a-m/joky/ghc-6.8.2/utils/ghc-pkg/ghc-pkg.bin)
  ld.so.1: ghc-pkg.bin: fatal: libm.so.2: open failed: No such file or
  directory
  Killed
  make[1]: *** [install] Error 137
  make[1]: Leaving directory `/export/home/a-m/joky/ghc-6.8.2/rts'
  make: *** [install] Error 2

 Are you using gmake?

 --
 aycan


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


[Haskell-cafe] Where can I get GHC for Solaris?

2009-07-07 Thread John Ky
Hi,

Anyone know where I can get the GHC compiler and libraries for Solaris?:

SunOS sun05 5.9 Generic_118558-30 sun4u sparc SUNW,Sun-Fire-280R

I tried to compile GHC myself and got the following error:

$ ./configure --enable-hc-boot
checking build system type... sparc-sun-solaris2.9
checking host system type... sparc-sun-solaris2.9
checking target system type... sparc-sun-solaris2.9
Canonicalised to: sparc-sun-solaris2
checking for ghc... no
checking for nhc... no
checking for nhc98... no
checking for hbc... no
checking for ld... /usr/ccs/bin/ld
checking for path to top of build tree... ./configure: -v0: command not
found
./configure: utils/pwd/pwd: No such file or directory
configure: error: cannot determine current directory

Thanks

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


Re: [Haskell-cafe] How to pretty print code efficiently

2009-07-05 Thread John Ky
Hi all,

Thanks everyone for the help.  The HughesPJ module works well for me.

Cheers,

-John

On Mon, Jul 6, 2009 at 3:49 AM, Chris Eidhof ch...@eidhof.nl wrote:

 On 4 jul 2009, at 05:13, Alexander Dunlap wrote:

  On Fri, Jul 3, 2009 at 6:45 PM, John Kynewho...@gmail.com wrote:

 Hi,

 Currently I'm pretty printing code by building arrays of strings and
 calling
 indent.  For example:

 instance JavaPrintableNamed AST.EnumeratedType where
   javaLinesNamed parentName (AST.EnumeratedType memberDefinitions) =
  [ public enum  ++ asJavaId(parentName)
  , {
  ] ++ memberCodeLines ++
  [ }
  , 
  ]
  where
 memberCodeLines = indent $ javaLines memberDefinitions

 The indent function takes a list of strings and adds an indent to the
 beginning of every line.

 I can imagine this to be very inefficient as it builds many strings and
 concatenates them.

 In Ruby, I might do the same thing like this:

 class EnumeratedType  JavaPrintableNamed
   def writeTo(writer)
  writer.print public enum 
  writer.puts self.asJavaId
  writer.puts {
  writer.indent do
 self.memberDefinitions.writeTo(writer)
 writer.puts
  end

 where above, the writer.indent takes care of the indent, and everything
 is
 appended to a stream, which doesn't seem so bad in terms of efficiency.

 I'm looking for a way to do something similar in Haskell.

 Anyone can give me a hand?

 Thanks

 -John


 ___


 You may want to investigate the standard module
 Text.PrettyPrint.HughesPJ, which contains a number of (I assume fairly
 efficient) combinators for pretty printing.


 I second that. Also, there is uulib which has a pretty printing module
 that's quite similar:


 http://hackage.haskell.org/packages/archive/uulib/0.9.10/doc/html/UU-PPrint.html

 I think both packages are based on the paper The Design of a
 Pretty-printing Library which can be found at
 http://www.cs.chalmers.se/~rjmh/Papers/pretty.pshttp://www.cs.chalmers.se/%7Erjmh/Papers/pretty.ps

 Not only do they provide abstractions for things like indentation,
 concatenation in different forms, etc., but they also are  more efficient
 than a naive implementation using lists.

 -chris

 -chris

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


[Haskell-cafe] How to pretty print code efficiently

2009-07-03 Thread John Ky
Hi,

Currently I'm pretty printing code by building arrays of strings and calling
indent.  For example:

instance JavaPrintableNamed AST.EnumeratedType where
   javaLinesNamed parentName (AST.EnumeratedType memberDefinitions) =
  [ public enum  ++ asJavaId(parentName)
  , {
  ] ++ memberCodeLines ++
  [ }
  , 
  ]
  where
 memberCodeLines = indent $ javaLines memberDefinitions

The indent function takes a list of strings and adds an indent to the
beginning of every line.

I can imagine this to be very inefficient as it builds many strings and
concatenates them.

In Ruby, I might do the same thing like this:

class EnumeratedType  JavaPrintableNamed
   def writeTo(writer)
  writer.print public enum 
  writer.puts self.asJavaId
  writer.puts {
  writer.indent do
 self.memberDefinitions.writeTo(writer)
 writer.puts
  end

where above, the writer.indent takes care of the indent, and everything is
appended to a stream, which doesn't seem so bad in terms of efficiency.

I'm looking for a way to do something similar in Haskell.

Anyone can give me a hand?

Thanks

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


Re: [Haskell-cafe] Record initialise question (RESOLVED)

2009-06-06 Thread John Ky
On Fri, Jun 5, 2009 at 8:05 PM, Martijn van Steenbergen 
mart...@van.steenbergen.nl wrote:

 Hi John,

 John Ky wrote:

full = do
   let myOrder = init -- [1]
{ item = Just init
   { itemId = Something
   }
, operation = Just Buy
}
   putStrLn $ show myOrder
   return ()

 Where initOrder and initItem are both replaced with just 'init' and the
 compiler works out from the context (ie. the type of the field) what the
 types are supposed to be and therefore the actual init function to call?


 Sure! This is one of the simplest forms of overloading. Here's a small
 example:

  data Circle = Circle { center :: (Float, Float), radius :: Float }
 data WrapCircle = WrapCircle { circle :: Circle }

 class Ini a where
  ini :: a

 instance Ini Circle where
  ini = Circle { center = (0, 0), radius = 1 }

 exampleCircle :: WrapCircle
 exampleCircle = WrapCircle { circle = ini { radius = 2 } }


 Hope this helps!

 Martijn.

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


[Haskell-cafe] Conversion from string to array

2009-06-06 Thread John Ky
Hi Haskell Cafe,

I'm trying to send stuff over UDP.  To do that, I've written a test program
that sends strings across.  That was fine, but I wanted to send binary data
too.  So I tried that only to find I am having difficulty putting together
some binary data.  For examples take the fromHex function in the following
code.
It is supposed to convert from a Hexadecimal string to a list of bytes, but
I am having trouble coercing the integer types to the size I want.

Is this the right way to do it?

Cheers,

-John

  import Data.Bits
  import Data.Char
  import Data.Word
  import System.Environment
  import XStream.Tsmr.Client

  data CmdLineOptions = CmdLineOptions
 { optionHelp :: Bool
 , optionVersion :: Bool
 , optionPort :: String
 , optionMessage :: String
 , optionInvalids :: [String]
 }
 deriving (Eq, Show)

  initCmdLineOptions = CmdLineOptions
 { optionHelp = False
 , optionVersion = False
 , optionPort = 1234
 , optionMessage = 
 }

  parseArgs :: [String] - CmdLineOptions
  parseArgs [] = initCmdLineOptions
  parseArgs (--port:port:xs) = (parseArgs xs) { optionPort = port }
  parseArgs (--help:xs) = (parseArgs xs) { optionHelp = True }
  parseArgs (--version:xs) = (parseArgs xs) { optionVersion = True }
  parseArgs (('-':opt):xs) = let option = (parseArgs xs) in
 option { optionInvalids = ('-':opt):optionInvalids option }
  parseArgs (message:xs) = (parseArgs xs) { optionMessage = message }

  printUsage = do
 putStrLn Usage: udp-server.lhs [options] message
 putStrLn 
 putStrLn Options:
 putStrLn   --help  Get help information.
 putStrLn   --vesionGet version information.
 putStrLn   --port nThe port number to listen on.
 putStrLn 
 putStrLn Message:
 putStrLn   The message to send.
 putStrLn 

  printVersion = do
 putStrLn Version.

  fromHex :: String - [Word8]
  fromHex [] = []
  fromHex (u:l:xs) = (hexU .|. hexL):fromHex xs
 where
hexU = (fromInteger $ hexValue u) :: Word8
hexL = (fromInteger $ hexValue l) :: Int
hexValue c
   | '0' = c  c = '9' = ord c - ord '0'
   | 'a' = c  c = 'z' = ord c - ord 'a' + 10


  run port message = do
 h - openlog localhost port udp-client.lhs
 syslog h (fromHex message)

  main = do
 args - getArgs
 let options = parseArgs args
 let port = optionPort options
 let message = optionMessage options
 if optionHelp options
then printUsage
else if optionVersion options
   then printVersion
   else do
  putStrLn (Starting UDP listener on port:  ++ port)
  run port message
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


[Haskell-cafe] Why are these record accesses ambiguous

2009-06-06 Thread John Ky
Hi Haskell Cafe,

In the following code, I get an error saying Ambiguous occurrence `x'.  Why
can't Haskell work out which x to call based on the type of getA?

Thanks

-John

#!/usr/bin/env runhaskell

 {-# LANGUAGE DisambiguateRecordFields #-}
 import A
 import B

 main = do
let xx = getA
putStrLn $ show x xx

--

module A where

data TypeA = TypeA
   { a :: Int
   , x :: Int
   }

getA = TypeA { a = 1, x = 2 }

-

module B where

data TypeB = TypeB
   { b :: Int
   , x :: Int
   }

getB = TypeB { b = 1, x = 3 }

--

./test.lhs:8:21:
Ambiguous occurrence `x'
It could refer to either `A.x', imported from A at ./test.lhs:3:2-9
  (defined at A.hs:5:5)
  or `B.x', imported from B at ./test.lhs:4:2-9
  (defined at B.hs:5:5)
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Why are these record accesses ambiguous

2009-06-06 Thread John Ky
Hi Luke,

You're right.  My code had a typo.  Unfortunately, I still get the same
error whichever way I do it.

For example:

 {-# LANGUAGE DisambiguateRecordFields #-}
 import A
 import B

 main = do
let xx = getA
print (x xx)

and:

#!/usr/bin/env runhaskell

 {-# LANGUAGE DisambiguateRecordFields #-}
 import A
 import B

 main = do
let xx = getA
putStrLn $ show (x xx)

both give me:

test.lhs:8:22:
Ambiguous occurrence `x'
It could refer to either `A.x', imported from A at test.lhs:3:2-9
  (defined at A.hs:5:5)
  or `B.x', imported from B at test.lhs:4:2-9
  (defined at B.hs:5:5)

Any ideas?

$ ghc --version
The Glorious Glasgow Haskell Compilation System, version 6.10.3

Thanks,

-John

On Sat, Jun 6, 2009 at 6:41 PM, Luke Palmer lrpal...@gmail.com wrote:

 On Sat, Jun 6, 2009 at 1:48 AM, John Ky newho...@gmail.com wrote:

 Hi Haskell Cafe,

 In the following code, I get an error saying Ambiguous occurrence `x'.
 Why can't Haskell work out which x to call based on the type of getA?

 Thanks

 -John

 #!/usr/bin/env runhaskell

  {-# LANGUAGE DisambiguateRecordFields #-}
  import A
  import B
 
  main = do
 let xx = getA
 putStrLn $ show x xx


 This is parsed as two arguments passed to the show function (which only
 takes one argument).

 putStrLn $ show (x xx)

 Or because putStrLn . show = print;

 print $ x xx




 --

 module A where

 data TypeA = TypeA
{ a :: Int
, x :: Int
}

 getA = TypeA { a = 1, x = 2 }

 -

 module B where

 data TypeB = TypeB
{ b :: Int
, x :: Int
}

 getB = TypeB { b = 1, x = 3 }

 --

 ./test.lhs:8:21:
 Ambiguous occurrence `x'
 It could refer to either `A.x', imported from A at ./test.lhs:3:2-9
   (defined at A.hs:5:5)
   or `B.x', imported from B at ./test.lhs:4:2-9
   (defined at B.hs:5:5)


 ___
 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] Record initialise question

2009-06-05 Thread John Ky
Hi all,

I have some sample code:

  full = do
 let myOrder = initOrder
  { item = Just initItem
 { itemId = Something
 }
  , operation = Just Buy
  }
 putStrLn $ show myOrder
 return ()

This is just a test project, but in a real project, I would have a more
elaborate structure.

Notice initOrder and initItem.  I actually need to know the type of field I
am initialising or the name of the corresponding function that provides
default values.  Is there any kind of polymorphic magic that lets me do this
instead?


  full = do
 let myOrder = init -- [1]
  { item = Just init
 { itemId = Something
 }
  , operation = Just Buy
  }
 putStrLn $ show myOrder
 return ()

Where initOrder and initItem are both replaced with just 'init' and the
compiler works out from the context (ie. the type of the field) what the
types are supposed to be and therefore the actual init function to call?

Thanks,

-John

[1] The second example is silly because there isn't actually any context at
this point, but let's pretend there is.
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


[Haskell-cafe] Type families not as useful over functions

2009-02-12 Thread John Ky
Hi Haskell Cafe,

I tried using type families over functions, but when I try it complains that
the two lines marked conflict with each other.

class Broadcast a where
   type Return a
   broadcast :: a - Return a

instance Broadcast [a - r] where
   type Return [a - r] = a - [r] -- Conflict!
   broadcast fs a = []

instance Broadcast [a - b - r] where
   type Return [a - b - r] = a - b - [r] -- Conflict!
   broadcast fs a b = []

Given that in Haskell, every function of n+1 arguments is also a function of
n arguments, this is likely the cause of the conflict.

In this case, currying is not my friend.

Unfortunately this means I'm stuck with numbered function names:

bc0 :: [r] - [r]
bc0 rs = rs

bc1 :: [a - r] - a - [r]
bc1 [] a = []
bc1 (r:rs) a = (r a):bc1 rs a

bc2 rs a b = rs `bc1` a `bc1` b

bc3 rs a b c = rs `bc1` a `bc1` b `bc1` c

-- etc

Cheers,

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


Re: [Haskell-cafe] Type families not as useful over functions

2009-02-12 Thread John Ky
Hi Miguel,

That's a nice way of writing it.

Thanks,

-John

On Fri, Feb 13, 2009 at 10:42 AM, Miguel Mitrofanov
miguelim...@yandex.ruwrote:

 What do you need that for?

 Can you live with

 infixl |$|
 (|$|) :: [a - r] - a - [r]
 fs |$| x = map ($ x) fs

 and, instead of broadcast fs a b use

 fs |$| a |$| b

 ?


 On 13 Feb 2009, at 02:34, John Ky wrote:

  Hi Haskell Cafe,

 I tried using type families over functions, but when I try it complains
 that the two lines marked conflict with each other.

 class Broadcast a where
   type Return a
   broadcast :: a - Return a

 instance Broadcast [a - r] where
   type Return [a - r] = a - [r] -- Conflict!
   broadcast fs a = []

 instance Broadcast [a - b - r] where
   type Return [a - b - r] = a - b - [r] -- Conflict!
   broadcast fs a b = []

 Given that in Haskell, every function of n+1 arguments is also a function
 of n arguments, this is likely the cause of the conflict.

 In this case, currying is not my friend.

 Unfortunately this means I'm stuck with numbered function names:

 bc0 :: [r] - [r]
 bc0 rs = rs

 bc1 :: [a - r] - a - [r]
 bc1 [] a = []
 bc1 (r:rs) a = (r a):bc1 rs a

 bc2 rs a b = rs `bc1` a `bc1` b

 bc3 rs a b c = rs `bc1` a `bc1` b `bc1` c

 -- etc

 Cheers,

 -John

 ___
 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] Type families not as useful over functions

2009-02-12 Thread John Ky
Hi Johnaton,

Ah yes.  That makes sense.  Is there a way to define type r to be all types
except functions?

-John

On Fri, Feb 13, 2009 at 10:44 AM, Jonathan Cast
jonathancc...@fastmail.fmwrote:

 On Fri, 2009-02-13 at 10:34 +1100, John Ky wrote:
  Hi Haskell Cafe,
 
  I tried using type families over functions, but when I try it
  complains that the two lines marked conflict with each other.
 
  class Broadcast a where
 type Return a
 broadcast :: a - Return a

  instance Broadcast [a - r] where
 type Return [a - r] = a - [r] -- Conflict!
 broadcast fs a = []
 
  instance Broadcast [a - b - r] where
 type Return [a - b - r] = a - b - [r] -- Conflict!
 broadcast fs a b = []
 
  Given that in Haskell, every function of n+1 arguments is also a
  function of n arguments, this is likely the cause of the conflict.

 This solution is somewhat in-extensible in the ultimate result type (r,
 in your code); if the number of types r can take on is limited, it
 should work well, though.  For expository purposes, I assume that r is
 always Int:

  -- | Conal Elliot's semantic editor combinator argument
  argument :: (a - a') - (a - b) - (a' - b)
  argument f g = g . f

  class Broadcast a where
type Return a
broadcast :: [a] - Return a
   instance Broadcast Int where
type Return Int = [Int]
broadcast ns = ns
  instance Broadcast r = Broadcast (a - r) where
type Return (a - r) = a - Return r
broadcast fs x = (map.argument) (const x) fs

 jcc

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


[Haskell-cafe] Writing a generic event handler

2009-02-11 Thread John Ky
Hi Haskell Cafe,

I'm interested in writing some events and event handlers in Haskell.  I
already have a Loop data structure, and I intend to use it for this purpose:

-- Create event
tEvent - newLoop (return ())

-- Register event handlers
tHandler1 - newLoop (putStrLn Handler1)
tHandler2 - newLoop (putStrLn Handler2)
splice tEvent tHandler1
splice tEvent tHandler2

-- Fire event
action - doLoop tEvent
action

doLoop :: Monad m = TVar (Loop (m ())) - STM (m ())
doLoop tLoop = do
   aLoop - readAsList tLoop
   return $ sequence_ aLoop

My question is: Is it possible to write a generic doLoop that works over
arbitrary functions?

For instance the following code wouldn't work because the event provides one
argument and the handler takes one argument:

-- Create event
tEvent - newLoop (\x - return ())

-- Register event handlers
tHandler1 - newLoop (\x - putStrLn (Handler1 ++ show x))
tHandler2 - newLoop (\x - putStrLn (Handler2 ++ show x))
splice tEvent tHandler1
splice tEvent tHandler2

-- Fire event
action - doLoop tEvent
action 123


Thanks,

-John

Full source code for Loop type:

module Fx.STM.Loop where

import Control.Monad
import Fx.STM.Util
import GHC.Conc
import System.IO.Unsafe

-- Transactional loop.  A loop is a circular link list.
data Loop a
   = ItemLink
  { item :: a
  , prev :: TVar (Loop a)
  , next :: TVar (Loop a)
  }

-- Create a new empty transactional loop.
newLoop :: a - STM (TVar (Loop a))
newLoop item = do
   tLoop - newTVar undefined
   writeTVar tLoop (ItemLink item tLoop tLoop)
   return tLoop

-- Splice two transactional loops.  This will join two loops if they were
-- originally separate, or split a single loop if the links were originally
-- part of the same loop.  No change occurs if the two links are identical.
splice :: TVar (Loop a) - TVar (Loop a) - STM ()
splice tLink0 tLink1 = do
   aLink0 - readTVar tLink0
   aLink1 - readTVar tLink1
   let tLink0Prev = prev aLink0
   let tLink1Prev = prev aLink1
   writeTVar tLink0 aLink0 { prev = tLink1Prev }
   writeTVar tLink1 aLink1 { prev = tLink0Prev }
   aLink0Prev - readTVar tLink0Prev
   aLink1Prev - readTVar tLink1Prev
   writeTVar tLink0Prev aLink0Prev { next = tLink1 }
   writeTVar tLink1Prev aLink1Prev { next = tLink0 }
   return ()

-- Unlink a single link from a transactional loop.
unlink :: TVar (Loop a) - STM ()
unlink tLink = do
   (ItemLink item tLinkPrev tLinkNext) - readTVar tLink
   aLinkPrev - readTVar tLinkPrev
   writeTVar tLinkPrev aLinkPrev { next = tLinkNext }
   aLinkNext - readTVar tLinkNext
   writeTVar tLinkNext aLinkNext { prev = tLinkPrev }
   writeTVar tLink (ItemLink item tLink tLink)
   return ()

-- Read the length of the loop.
readLength :: TVar (Loop a) - STM Int
readLength tLink = do
   list - readAsList tLink
   return $ length list

readLinks :: TVar (Loop a) - STM [TVar (Loop a)]
readLinks tLink = readLinksUntil tLink tLink

readLinksUntil :: TVar (Loop a) - TVar (Loop a) - STM [TVar (Loop a)]
readLinksUntil tLink tLinkEnd = do
   (ItemLink _ tLinkPrev tLinkNext) - readTVar tLink
   return []
   if tLinkNext == tLinkEnd
  then return [tLink]
  else do
 tail - readLinksUntil tLinkNext tLinkEnd
 return $ tLink:tail

-- Read the elements of the loop as a list starting from tLink.
readAsList :: TVar (Loop a) - STM [a]
readAsList tLink = readAsListUntil tLink tLink

-- Read the elements of the loop as a list starting from tLink
-- and terminating non-inclusively at tLinkEnd.
readAsListUntil :: TVar (Loop a) - TVar (Loop a) - STM [a]
readAsListUntil tLink tLinkEnd = do
   (ItemLink item tLinkPrev tLinkNext) - readTVar tLink
   if tLinkNext == tLinkEnd
  then return [item]
  else do
 tail - readAsListUntil tLinkNext tLinkEnd
 return $ item:tail

-- Create a new loop from a list.
newFromList :: [a] - STM (TVar (Loop a))
newFromList [item] = newLoop item
newFromList (item:items) = do
   tLink - newLoop item
   tLinkRest - newFromList items
   splice tLink tLinkRest
   return tLink

doLoop :: Monad m = TVar (Loop (m ())) - STM (m ())
doLoop tLoop = do
   aLoop - readAsList tLoop
   return $ sequence_ aLoop
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


[Haskell-cafe] Why does sleep not work?

2009-02-09 Thread John Ky
Hi Haskell Cafe,

I wrote very short program to sleep for 5 seconds compiled with the
-threaded option in ghc on the Mac OS X 1.5.

I am finding that using the sleep function doesn't sleep at all, whereas
using threadDelay does:

main = do
  putStrLn Waiting for 5 seconds.
  threadDelay 500 -- works
  putStrLn Done.

main = do
  putStrLn Waiting for 5 seconds.
  sleep 5 -- doesn't sleep at all
  putStrLn Done.

Anybody know what's happening?

Thanks

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


Re: [Haskell-cafe] Why does sleep not work?

2009-02-09 Thread John Ky
Hi Peter,

Source code:
import System.IO
import System.Posix

main = do
  putStrLn Waiting for 5 seconds.
  sleep 5 -- doesn't sleep at all
  putStrLn Done.

OS:
Mac OS X 10.5

Compile command:
ghc --threaded testsleep.hs

If I remove --threaded, then it does sleep.

Thanks,

-John

On Tue, Feb 10, 2009 at 8:59 AM, Peter Verswyvelen bugf...@gmail.comwrote:

 Hi John,
 Which sleep are you using? From which module? Can you show the full source
 with import statements?

 Cheers,
 Peter

 2009/2/9 John Ky newho...@gmail.com

 Hi Haskell Cafe,

 I wrote very short program to sleep for 5 seconds compiled with the
 -threaded option in ghc on the Mac OS X 1.5.

 I am finding that using the sleep function doesn't sleep at all, whereas
 using threadDelay does:

 main = do
   putStrLn Waiting for 5 seconds.
   threadDelay 500 -- works
   putStrLn Done.

 main = do
   putStrLn Waiting for 5 seconds.
   sleep 5 -- doesn't sleep at all
   putStrLn Done.

 Anybody know what's happening?

 Thanks

 -John


 ___
 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] Type families are awesome

2009-01-27 Thread John Ky
Thanks Luke,

Works great.

On Wed, Jan 21, 2009 at 7:35 PM, Luke Palmer lrpal...@gmail.com wrote:

 2009/1/21 John Ky newho...@gmail.com

 *Main let x = lookup
 *Main let y = Fx.Data.Map.lookup

 interactive:1:8:
 Ambiguous type variable `ma' in the constraint:
   `Fx.Data.Map.MapType ma'
 arising from a use of `Fx.Data.Map.lookup' at interactive:1:8-25
 Probable fix: add a type signature that fixes these type variable(s)


 I think this is just the monomorphism restriction. Turn it off with
 -XNoMonomorphismRestriction, or add a parameter to the binding:

 let x k = lookup k

 Luke

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


[Haskell-cafe] Type families are awesome

2009-01-21 Thread John Ky
Hi Haskell Cafe,

I'm finding that I really like type families.  For instance, the
GHC.List.lookup and Data.Map.lookup functions annoy me because their names
clash, yet their type are so similar.  With type families, I could define a
more generic lookup function like this:

import Data.Map as MAP
import GHC.List as LIST

class MapType ma where
   type Key ma
   type Item ma
   lookup :: Key ma - ma - Maybe (Item ma)

instance (Ord ka) = MapType (MAP.Map ka a) where
   type Key (MAP.Map ka a) = ka
   type Item (MAP.Map ka a) = a
   lookup ka ma = MAP.lookup ka ma

instance (Eq ka) = MapType [(ka, a)] where
   type Key [(ka, a)] = ka
   type Item [(ka, a)] = a
   lookup ka ma = LIST.lookup ka ma

This lookup function works on both Map ka a and [(ka, a)] types and I no
longer need to qualify my lookup function with the module name.

The downside I suppose is that lookup is no longer a function that can be
manipulated freely:

*Main let x = lookup
*Main let y = Fx.Data.Map.lookup

interactive:1:8:
Ambiguous type variable `ma' in the constraint:
  `Fx.Data.Map.MapType ma'
arising from a use of `Fx.Data.Map.lookup' at interactive:1:8-25
Probable fix: add a type signature that fixes these type variable(s)

A shame that.  I had been hoping it would be possible to have a generic
lookup function that could be used in every way the current collection of
various lookup functions can be used.

So much nicer if 'y' above could be bound to the Fx.Data.Map.lookup with the
same type:

*Main :t Fx.Data.Map.lookup
Fx.Data.Map.lookup :: forall ma.
  (Fx.Data.Map.MapType ma) =
  Fx.Data.Map.Key ma - ma - Maybe (Fx.Data.Map.Item
ma)

And then have the ambiguity resolve later when 'y' is actually used.

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


[Haskell-cafe] Different return type?

2009-01-18 Thread John Ky
Hi,

Possibly a silly question but is it possible to have a function that has a
different return type based on it's first argument?

For instance

data Person = Person { name :: String, ... }
data Business = Business { business_number :: Int, ...}

key person = name person
key business = business_number business

Thanks

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


Re: [Haskell-cafe] Different return type?

2009-01-18 Thread John Ky
Hi Daniel,

When would I use either?  What are the trade-offs?

Thanks

-John

On Mon, Jan 19, 2009 at 1:13 PM, Daniel Fischer daniel.is.fisc...@web.dewrote:

 Am Montag, 19. Januar 2009 02:44 schrieb John Ky:
  Hi,
 
  Possibly a silly question but is it possible to have a function that has
 a
  different return type based on it's first argument?
 
  For instance
 
  data Person = Person { name :: String, ... }
  data Business = Business { business_number :: Int, ...}
 
  key person = name person
  key business = business_number business
 
  Thanks
 
  -John

 Well, you could use

 {-# LANGUAGE MultiParamTypeClasses, FunctionalDependencies,
 TypeSynonymInstances #-}
 module Key where

 data Person = Person { name :: String }
 data Business = Business { business_number :: Int}

 class Key a b | a - b where
key :: a - b

 instance Key Person String where
key = name

 instance Key Business Int where
key = business_number

 or with type families:
 {-# LANGUAGE TypeFamilies #-}
 class Key2 a where
type Res a
key2 :: a - Res a

 instance Key2 Person where
type Res Person = String
key2 = name

 instance Key2 Business where
type Res Business = Int
key2 = business_number


 but apart from that and parametrically polymorphic functions (of type a -
 [a]
 or the like), I don't think it's possible, it would need dependent types.

 HTH,
 Daniel

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


[Haskell-cafe] Debugging STM

2009-01-08 Thread John Ky
Hi,

Does anyone have any advice on how to inspect complex TVar data structures
that may include cycles?  They're opaque as far as Show goes.  And sometimes
I'd like a more comprehensive view of my data structures at the ghci prompt
rather than the dribs and drabs I get by typing x - atomically $ readTVar
var and the like all the time.  Also, do TVars have a printable identity
for debugging purposes?

Thanks

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


Re: [Haskell-cafe] Re: Tying a simple circularly STM linked list

2009-01-07 Thread John Ky
Thanks Chris,

The undefined works for me.

-John

On Wed, Jan 7, 2009 at 11:11 AM, ChrisK hask...@list.mightyreason.comwrote:

 You can use undefined or error ... :

  {-# LANGUAGE RecursiveDo #-}
 import Control.Concurrent.STM
 import Control.Monad.Fix

 -- Transactional loop.  A loop is a circular link list.
 data Loop a
   = ItemLink
  { item :: a
  , prev :: TVar (Loop a)
  , next :: TVar (Loop a)
  }

 -- Create a new empty transactional loop.
 newLoop :: a - STM (TVar (Loop a))
 newLoop item = do
   tLoop - newTVar undefined
   writeTVar tLoop (ItemLink item tLoop tLoop)
   return tLoop


 Hmmm.. STM does not have a MonadFix instance.  But IO does:


 -- Use MonadFix instance of newLoopIO
 newLoopIO :: a - IO (TVar (Loop a))
 newLoopIO item = mfix (\ tLoop - newTVarIO (ItemLink item tLoop tLoop))


 But mfix (like fix) is difficult to read in large amounts, so there is
 mdo:

  -- Use RecursiveDo notation
 newLoopMDO :: a - IO (TVar (Loop a))
 newLoopMDO item = mdo
   tLoop - newTVarIO (ItemLink item tLoop tLoop)
   return tLoop



 Cheers,
  Chris




 ___
 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] Tying a simple circularly STM linked list

2009-01-06 Thread John Ky
Hi,

I've written a circularly linked list, but there is some code in it I feel
is redundant, but don't know how to get rid of:

-- Transactional loop.  A loop is a circular link list.
data Loop a
   = ItemLink
  { item :: a
  , prev :: TVar (Loop a)
  , next :: TVar (Loop a)
  }
   | InitLink

-- Create a new empty transactional loop.
newLoop :: a - STM (TVar (Loop a))
newLoop item = do
   tLoop - newTVar InitLink
   writeTVar tLoop (ItemLink item tLoop tLoop)
   return tLoop

In the above, the InitLink value is only ever used in the newLoop function
to create a single one element circular linked list.  Is there a way to
write newLoop to avoid using this value?

Thanks

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


[Haskell-cafe] Transactional container for storing anonymous deletable objects

2008-12-28 Thread John Ky
Hi,

I need a container data structure for storing anonymous objects - most
likely things that have not value such as STM (), but probably other things
as well.  This will allow me to later on, iterate over the container and
process those objects.  Additionally I have the requirement that I need to
be able to remove individual objects from this container.  It needs to be
linear time.

main = do
   container - nil
   key1 - cons 1 container
   key2 - cons 2 container
   key3 - cons 3 container
   key4 - cons 4 container
   key5 - cons 5 container
   unlink key3 container
   unlink key2 container
   unlink key4 container
   list - toList container
   putStrLn (show list)

The above should give: [1, 5]

What should I use?

Thanks

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


[Haskell-cafe] Data.Map add only if not exist and return true if added

2008-12-09 Thread John Ky
Hi,

I'm looking for a function for Data.Map that will insert a new key and value
into the map if the key doesn't already exist in the map.  When the key
already exists, I don't want the value updated in the map.  Additionally, I
want to know whether the key/value was inserted or not so that I can return
that fact as a boolean from my function.

I can't work out which function in Data.Map is suitable for this task and I
wanted to avoid two lookups.

Thanks,

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


[Haskell-cafe] Deriving something else?

2008-12-08 Thread John Ky
Hi,

I've defined a class and some instances, which I'm hoping would help me
show values of types that may include transactional elements.

class TShow a where
   tshow :: a - IO String

instance Show (TVar a) where
   show = %

instance (Show a) = TShow a where
   tshow a = return $ show a

instance (Show a) = TShow (TVar a) where
   tshow ta = do
  a - readTVar ta
  return $ show a

Having created a new class is it possible to do some magic so that it can be
put it into a deriving clause?

data Type = Type
   { field1 :: Int
   , field2 :: Int
   }
   deriving Show

data AnotherType = AnotherType
   { field3 :: Int
   , field4 :: TVar Type
   }
   deriving *TShow*

Thanks

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


[Haskell-cafe] Overlapping instances

2008-12-08 Thread John Ky
Hi,

I've got the following code which tries to implement a TShow class, which is
equivalent to Show, except it is supposed to work on TVar types as well.

import GHC.Conc

createEngine :: String - Int - Int - IO Engine
createEngine name major minor = do
   tUsers - newTVarIO []
   return $ Engine
  { engineName = name
  , version = EngineVersion
 { major = major
 , minor = minor
 }
  , users = tUsers
  }

class TShow a where
   tshow :: a - IO String

instance Show (TVar a) where
   show a = %

instance (Show a) = TShow a where
   tshow a = return $ show a

instance (Show a) = TShow (TVar a) where
   tshow ta = do
  a - atomically (readTVar ta)
  return $ show a

data User = User
   { userName :: String
   }
   deriving Show

data EngineVersion = EngineVersion
   { major :: Int
   , minor :: Int
   }
   deriving Show

data Engine = Engine
   { engineName :: String
   , version :: EngineVersion
   , users :: TVar [User]
   }

instance TShow Engine where
   tshow a = do
  users - atomically (readTVar (users a))
  return $
 Engine {  ++
 engineName =  ++ show (engineName a) ++ ,  ++
 version =  ++ show (version a) ++ ,  ++
 users = % ++ show users ++  }

When I run it however, I get this:

*Main te - createEngine Hello 1 2
*Main s - tshow te

interactive:1:5:
Overlapping instances for TShow Engine
  arising from a use of `tshow' at interactive:1:5-12
Matching instances:
  instance (Show a) = TShow a -- Defined at fxmain.hs:(26,0)-(27,27)
  instance TShow Engine -- Defined at fxmain.hs:(51,0)-(58,41)
In a stmt of a 'do' expression: s - tshow te

I'm not seeing how instance (Show a) = TShow a in the above error message
is applicable here since Engine is not an instance of Show.  Why is it
complaining?

Thanks,

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


[Haskell-cafe] Reading showables

2008-12-07 Thread John Ky
Hi,

Is there a way to read Showables?

main = do
putStrLn $ show $ read

Thanks

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


Re: [Haskell-cafe] Reading showables

2008-12-07 Thread John Ky
Hi Thomas,

So show . read and \x - show (read x) are actually mean different
things?

Also, I never suspected that something like this should succeed:

putStrLn $ (read . show) $ [EMAIL PROTECTED]

Thanks,

-John

On Mon, Dec 8, 2008 at 12:38 AM, Thomas Hartman [EMAIL PROTECTED] wrote:

 John,

  By convention, read . show is supposed to be id.

  However, in real life, this is often not the case. It all depends on
 the implementor, and this is a convention that seems to be broken
 pretty frequently.

  Often there is a show instance with no read or vice versa, and
 sometimes even when there is both read and show they are not inverses.

  Thomas.

 main = show . read



 Am 7. Dezember 2008 14:11 schrieb John Ky [EMAIL PROTECTED]:
  Hi,
 
  Is there a way to read Showables?
 
  main = do
  putStrLn $ show $ read
 
  Thanks
 
  -John
 
 
  ___
  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] Is unsafePerformIO safe here?

2008-12-07 Thread John Ky
Hi,

Is the following safe?

moo :: TVar Int
moo = unsafePerformIO $ newTVarIO 1

I'm interested in writing a stateful application, and I wanted to start with
writing some IO functions that did stuff on some state and then test them
over long periods of time in GHCi.

I was worried I might be depending on some guarantees that aren't actually
there, like moo being discarded and recreated inbetween invocations of
different functions.

Thanks,

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


Re: [Haskell-cafe] Reading showables

2008-12-07 Thread John Ky
Thanks for the clarification.

They're all the same, as you've explained:

Prelude putStrLn $ (show . read) 123
*** Exception: Prelude.read: no parse

Prelude putStrLn $ show $ read 123
*** Exception: Prelude.read: no parse

Prelude putStrLn $ (\x - show (read x)) 123
*** Exception: Prelude.read: no parse

-John

On Mon, Dec 8, 2008 at 12:08 PM, Jonathan Cast [EMAIL PROTECTED]wrote:

 On Mon, 2008-12-08 at 11:16 +1100, John Ky wrote:
  Hi Thomas,
 
  So show . read and \x - show (read x) are actually mean different
  things?

 No.  Of course not.  But there's no guarantee that

show (read x) = x

 either.

  Also, I never suspected that something like this should succeed:
 
  putStrLn $ (read . show) $ [EMAIL PROTECTED]

 Of course it succeeds.  You put the `show' first; show always succeeds
 and --- for the Show instances in the Prelude, plus some ---

   read (show x) = x

 for finite, total x.

 (Note that read . show /= show . read; they don't even have the same
 type!

  show . read :: forall alpha. Show alpha = String - String
  read . show :: forall alpha beta. (Read alpha, Show beta) = alpha -
 beta

 NB: The reason why show . read is illegal should be screaming out at you
 about now.  The caveat --- other than the one I mentioned above --- to
 claims that read . show = id should also be screaming out.)

 jcc

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


Re: [Haskell-cafe] Is unsafePerformIO safe here?

2008-12-07 Thread John Ky
Does that mean there is no place to store state while running the
interpreter and that I have to put the state elsewhere such as a file?  I
was hoping to avoid that as I'm only prototyping at this stage and don't
want to write a persistent layer just yet.

Thanks

-John

On Mon, Dec 8, 2008 at 11:51 AM, Thomas Davie [EMAIL PROTECTED] wrote:


 On 8 Dec 2008, at 01:28, John Ky wrote:

  Hi,

 Is the following safe?

 moo :: TVar Int
 moo = unsafePerformIO $ newTVarIO 1

 I'm interested in writing a stateful application, and I wanted to start
 with writing some IO functions that did stuff on some state and then test
 them over long periods of time in GHCi.

 I was worried I might be depending on some guarantees that aren't actually
 there, like moo being discarded and recreated inbetween invocations of
 different functions.


 Define safe... In this case though, I would guess it's not safe.  The
 compiler is free to call moo zero, one or many times depending on its
 evaluation strategy, and when it's demanded.  It's possible that your TVar
 will get created many times, and different values returned by the constant
 moo.

 That sounds pretty unsafe to me.

 Bob

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


Re: [Haskell-cafe] Is unsafePerformIO safe here?

2008-12-07 Thread John Ky
Inline.

On Mon, Dec 8, 2008 at 1:28 PM, Luke Palmer [EMAIL PROTECTED] wrote:

 2008/12/7 John Ky [EMAIL PROTECTED]

 Does that mean there is no place to store state while running the
 interpreter and that I have to put the state elsewhere such as a file?  I
 was hoping to avoid that as I'm only prototyping at this stage and don't
 want to write a persistent layer just yet.


 Bob is right, that technically it is unsafe.  However, in GHC (I can't
 speak for the others) you can make it safe by forcing it not to inline.
  Then, IIRC, you are guaranteed (only in GHC, not in Haskell) that it will
 be only created once:

 moo :: TVar Int
 {-# NOINLINE moo #-}
 moo = unsafePerformIO $ newTVarIO 1


Will keep that in mind.


 Correct, you cannot have global state in safe Haskell.  Make of that what
 you will, YMMV, personally I like it (it has positive implications in terms
 of semantics and reasoning).  You have to put state elsewhere, but such as
 a file is a little extreme.  Make it at the GHCi prompt (if there is more
 than a teeny bit of initialization, I usually define a helper function to
 make this as easy as possible).


You mean like this?

Prelude x - GHC.Conc.atomically (GHC.Conc.newTVar 1)
Prelude GHC.Conc.atomically $ GHC.Conc.readTVar x
1

I could live with that.


Then pass it around or put your computation in a ReaderT (same thing).
  You're going to be passing it around when you write your real application
 anyway, right?


Will need to read up on ReaderT.  Thanks for the tip.

Also, as your application matures, you know your persistence layer is
 probably already done for you in Data.Binary :-)


Awesome.

 Thanks

-John


 Luke



 Thanks

 -John


 On Mon, Dec 8, 2008 at 11:51 AM, Thomas Davie [EMAIL PROTECTED]wrote:


 On 8 Dec 2008, at 01:28, John Ky wrote:

  Hi,

 Is the following safe?

 moo :: TVar Int
 moo = unsafePerformIO $ newTVarIO 1

 I'm interested in writing a stateful application, and I wanted to start
 with writing some IO functions that did stuff on some state and then test
 them over long periods of time in GHCi.

 I was worried I might be depending on some guarantees that aren't
 actually there, like moo being discarded and recreated inbetween 
 invocations
 of different functions.


 Define safe... In this case though, I would guess it's not safe.  The
 compiler is free to call moo zero, one or many times depending on its
 evaluation strategy, and when it's demanded.  It's possible that your TVar
 will get created many times, and different values returned by the constant
 moo.

 That sounds pretty unsafe to me.

 Bob



 ___
 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] What is this function?

2008-10-16 Thread John Ky
Hi,

I've written this function here:

   scramble [] = []
   scramble [x] = [[z] | z - scramble x]
   scramble (x:xs) =
  [(y:z)|y - scramble x, z - scramble xs]

and (I think) it roughly does what I want it to:

   *Main scramble ([]::[Int])
   []
   *Main scramble ([1]::[Int])
   [[1],[2]]
   *Main scramble ([1,2]::[Int])
   [[1,1],[1,2],[2,1],[2,2]]
   *Main scramble ([1,2,3]::[Int])
   [[1,1,1],[1,1,2],[1,2,1],[1,2,2],[2,1,1],[2,1,2],[2,2,1],[2,2,2]]

Three questions:

1. What should I call this function?
2. Is there already one in the standard library that does the same thing?
3. Is it possible to rewrite it with only scramble [] and scramble
(x:xs) and not the scramble[x]?

Thanks

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


Re: [Haskell-cafe] What is this function? (RESOLVED)

2008-10-16 Thread John Ky
Hi Luke,

Thankyou so much.  I need the sequence function.

What I was after was this:

class Scramblable a where
   scramble :: a - [a]

instance Scramblable [MyType] where
   scramble values = sequence (map scramble values)

instance Scramblable MyType where
   scramble myType = {- blah blah -}

I was basically after exhaustively generating lots ASTs given a template AST
with lots of leaf values changed.

Thanks,

-John

On Thu, Oct 16, 2008 at 8:39 PM, Luke Palmer [EMAIL PROTECTED] wrote:

 2008/10/16 John Ky [EMAIL PROTECTED]:
  Hi,
 
  I've written this function here:
 
 scramble [] = []
 scramble [x] = [[z] | z - scramble x]
 scramble (x:xs) =
[(y:z)|y - scramble x, z - scramble xs]
 
  and (I think) it roughly does what I want it to:
 
 *Main scramble ([]::[Int])
 []
 *Main scramble ([1]::[Int])
 [[1],[2]]

 So, um, this is nonsense.  You've given it only 1, and yet it outputs
 a 2, yet there is no mention of addition or the literal 2 anywhere in
 your function.

 This function looks a lot like the more sensible:

  scramble' n xs = sequence (replicate n xs)

  scramble' 0 [1,2,3]
 [[]]
  scramble' 1 [1,2,3]
 [[1],[2],[3]]
  scramble' 2 [1,2,3]
 [[1,1],[1,2],[1,3],[2,1],[2,2],[2,3],[3,1],[3,2],[3,3]]

 Where your examples all had [1,2] as the argument.

 Luke

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


[Haskell-cafe] How to do a special kind of comment with the TokenParser

2008-07-09 Thread John Ky
Hi,

TokenParser supports two kinds of comments, the multi-line comments (ie. {-
-}) and the single line comments (ie. -- \n).

The language I am trying to parse, however, has comments which are neither.
The -- acts like a single line comment which extends to the end of the line
usually, but can also be truncated to before the end of the line by another
--.  For example:

  noncomment -- comment comment
  noncomment -- comment comment -- noncomment noncomment -- comment --
noncomment
  noncomment

I haven't been able to get the TokenParser to work with this style of
comment.  The best I could do was copy the whole Token module and modify the
code:

data LanguageDef st
= LanguageDef
{  {- snip -}
*, commentLine:: String*
   {- snip -}
}

   {- snip -}

makeTokenParser languageDef
= TokenParser{   {- snip -}   }
where
   {- snip -}
  whiteSpace
| noLine  noMulti  = skipMany (simpleSpace *| customComment* ?
)
| noLine = skipMany (simpleSpace *| customComment* |
multiLineComment ? )
| noMulti= skipMany (simpleSpace *| customComment* |
oneLineComment ? )
| otherwise  = skipMany (simpleSpace *| customComment* |
oneLineComment | multiLineComment ? )
where
  noLine  = null (commentLine languageDef)
  noMulti = null (commentStart languageDef)
  *customComment =
do{commentCustom languageDef
  ;return()
}*

Then I put my specialised comment parser in the customComment field:

languageDef = TOKEN.LanguageDef
   {{- snip -}
   , TOKEN.commentCustom = customComment
{- snip -}
   }
   where
  customComment = do
 string --
 untilLineCommentEnd
 return ()

  untilLineCommentEnd = do
 c - manyTill anyChar (string \n | try (string --))
 return ()

Anyone know of a way I could reuse the TokenParser code rather than copy and
tweaking it?

Thanks

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


Re: [Haskell-cafe] GHC throws IOError on Win32 when there is no console

2007-02-11 Thread John Ky

Hi Paul,

Can I have your code that doesn't work?  I want to fiddle with it a bit.

Thanks

-John

On 2/12/07, Paul Moore [EMAIL PROTECTED] wrote:


On 09/02/07, Paul Moore [EMAIL PROTECTED] wrote:
 It probably wouldn't be hard to write a reasonably general wrapper for
 this, but it's a bit late now so I'll leave that as an exercise :-)

Sigh. I tried to set this up (using a little external C routine to do
the API grunt work) and it doesn't seem to work as I expect. Maybe the
C/GHC runtimes do something more complex than just using the API
standard handles, maybe I coded something wrong.

In theory, this should work. In practice, Haskell may benefit from an
equivalent of the C freopen() function (from stdio), which deals
correctly with the internals of handles...

Paul.

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


Re: [Haskell-cafe] GHC throws IOError on Win32 when there is no console

2007-02-10 Thread John Ky

Hi Duncan,

Thanks for your comments.  In the context of a haskell process running as a
Windows service, a message box is useless, because Haskell services do not
have a GUI and cannot interact with the desktop.

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


[Haskell-cafe] GHC throws IOError on Win32 when there is no console

2007-02-09 Thread John Ky

Hi,

I noticed on Windows that when I use IO functions that write to stdout when
the process is lacking a console, those functions throw an IOError.  I'm not
sure if this also occurs for stderr because I haven't tried it.

Some classes of processes are created without a console because they never
interact with the user and include System services.  Crashing with IOError
in this case is difficult to diagnose because because the only symptom is
the process crashes with no visible output.

I believe the most sensible behaviour should be for those functions to not
throw, but instead do nothing.

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


[Haskell-cafe] Re: GHC throws IOError on Win32 when there is no console

2007-02-09 Thread John Ky

Sorry, I should clarify.  I am writing about applications compiled with GHC.

-John

On 2/10/07, John Ky [EMAIL PROTECTED] wrote:


Hi,

I noticed on Windows that when I use IO functions that write to stdout
when the process is lacking a console, those functions throw an IOError.
I'm not sure if this also occurs for stderr because I haven't tried it.

Some classes of processes are created without a console because they never
interact with the user and include System services.  Crashing with IOError
in this case is difficult to diagnose because because the only symptom is
the process crashes with no visible output.

I believe the most sensible behaviour should be for those functions to not
throw, but instead do nothing.

-John


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


[Haskell-cafe] A function callable from C

2007-02-05 Thread John Ky

Hi,

The following code works:


type ServiceMainClosure = DWORD - IO ()

foreign import ccall wrapper
  mkServiceMainClosure :: ServiceMainClosure - IO (FunPtr

ServiceMainClosure)

But the following doesn't:


type ServiceMainClosure = DWORD - [String] - IO ()

foreign import ccall wrapper
  mkServiceMainClosure :: ServiceMainClosure - IO (FunPtr

ServiceMainClosure)

System\Win32\Service.hsc:108:8: parse error on input `import'

What can I do to get this to work?

Thanks

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


Re: [Haskell-cafe] A function callable from C

2007-02-05 Thread John Ky

Hi Stefan,

In that case, how do I marshall [String] to Ptr (Ptr CChar)?

Thanks

-John

On 2/6/07, Stefan O'Rear [EMAIL PROTECTED] wrote:


You have to use a type that C's tiny brain understains. IANAWP
but I'm guessing you want:

type ServiceMainClosure = DWORD - Ptr (Ptr CChar) - IO ()

foreign import ccall wrapper
  mkServiceMainClosure :: ServiceMainClosure - IO (FunPtr
ServiceMainClosure)

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


Re: [Haskell-cafe] A function callable from C

2007-02-05 Thread John Ky

Actually, what I need to do is a fair bit more complex than string
marshalling.  It feels like I'll need to pull together a number of different
concepts so I may as well describe the problem directly.

The C function I want to call is StartServiceCtrlDispatcher:

*BOOL* *StartServiceCtrlDispatcher(*
 *const LPSERVICE_TABLE_ENTRY* *lpServiceTable**
**);*

It takes an array of SERVICE_TABLE_ENTRY structures:

typedef struct _SERVICE_TABLE_ENTRY {
 LPTSTR lpServiceName;
 LPSERVICE_MAIN_FUNCTION lpServiceProc;
} SERVICE_TABLE_ENTRY,
*LPSERVICE_TABLE_ENTRY;

The typedef  LPSERVICE_MAIN_FUNCTION is something like:

*typedef (VOID WINAPI* *ServiceMain)(*
 *DWORD* *dwArgc**,
*  *LPTSTR** *lpszArgv**
**);*

It seems to me that I'll need to learn how to do the following:

* Represent SERVICE_TABLE_ENTRY AND LPSERVICE_TABLE_ENTRY structs as a
haskell type.
* Create an array of SERVICE_TABLE_ENTRY structs.
* Populate the array (they're null terminated).
* Do all sorts of elaborate marshalling so that the end product is a
sensibly typed Haskell function like this:

data ServiceTableEntry = ServiceTableEntry {
 serviceName :: String
 serviceProc :: [String] - IO ()
 }
startServiceCtrlDispatcher :: [ServiceTableEntry] - IO ()

That's quite a lot to chew on and I finding it challenging learning about
all these things and combining them at the same time.

I've attached the complete source to what I have so far in a zip file.

Thanks

-John

On 2/6/07, Stefan O'Rear [EMAIL PROTECTED] wrote:


On Tue, Feb 06, 2007 at 12:40:38PM +1100, John Ky wrote:
 Hi Stefan,

 In that case, how do I marshall [String] to Ptr (Ptr CChar)?

look at Foreign.C.String and Foreign.Ptr



service-002.rename_as_zip
Description: Binary data
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


[Haskell-cafe] Re: Win32 help please

2007-02-04 Thread John Ky

Hi,

I tried as suggested:


hsc2hs mywin32.hsc
ghc -c -O -fffi mywin32.hs


which allows me to use ghci.

And if I add a main function, I can also do this:


hsc2hs mywin32.hsc
ghc -fffi mywin32.hs -package Win32


Thanks everyone for the help.

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


[Haskell-cafe] Boost equivalent

2007-02-01 Thread John Ky

Hi,

Does the Haskell community have an equivalent to C++ community's Boost
project with the aim of writing libraries for the eventual inclusion into
Haskell?

Thanks

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


Re: [Haskell-cafe] Paths to tree

2007-01-30 Thread John Ky

Hi Tomasz,

I actually quite like this style.  I was able to understand it after
spending some time reading the docs for some of the functions you used.

My problem I guess is being able to write the code this way when the need
arises or even just recognising when and where it's an option, both of which
to me is considerably harder.

Thanks for the tip.

-John

On 1/29/07, Tomasz Zielonka [EMAIL PROTECTED] wrote:


On Mon, Jan 29, 2007 at 10:10:47PM +1100, John Ky wrote:
 I've written some code and was wondering if there was a better way to
write
 it in terms of readability, brevity and/or efficiency.

This version of mergeForest2 should be more efficient. For even better
efficiency it should use Data.Sequence for efficient concatenation
(instead of ++). I also made it more general. You have to judge
readability yourself.

import qualified Data.Map as Map

data ArcData = ArcData
 { name :: String
 } deriving (Show, Eq, Ord) -- derive Ord and Eq

mergeForest2 :: (Ord k) = [Tree k] - Forest k
mergeForest2 =
map pairToNode .
Map.toList .
Map.map mergeForest2 .
Map.fromListWith (++) .
map nodeToPair
  where
nodeToPair (Node x y) = (x, y)
pairToNode = uncurry Node

Best regards
Tomasz

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


Re: [Haskell-cafe] Re: Paths to tree

2007-01-30 Thread John Ky

Hi apfelmus,

Your code is fine, I like it. A minor hint is that mergeForest is a fold:

   mergeForest = foldr merge []
Also, we have
   prettyPrint = putStr . unlines . prettyPrint' $ forest



Nice help on the simple things.

I can't know, but it doesn't seem unreasonable that you intend to use

the ArcForest as a trie, i.e. an efficient implementation of a set of
paths which allows to look up quickly whether a given path (here of type
[String]) is in the set or not. So, we have



For a while, I was thinking what on Earth are you talking about, even while
I continued reading the rest of the email, but it eventually clicked what
you where trying to show me - which was something I didn't dare try until I
got more familiar with Haskell.

You're examples got me started on dealing with these sorts of complex tree
structures (or tries as you call them).  They made more sense as I spent
more time reading and rereading them.

Now, we can build up our finite map for paths:


   data MapPath v = TriePath (Maybe v) (MapString (MapPath v))

because it (maybe) contains a value for the key '[] :: Path' and it
(maybe) contains a map of paths that is organized by their first String
element.



In my own code I had to diverge from your definition because for my needs,
every node needed to contain a value (even if it was a default value).  I
plan to later add other numerical values to every node so that I can
traverse them and do calculations that feed up and trickle down the tree.

Now what about 'MapString v', how do we get this? Well, your

implementation corresponds to the choice

  type MapString v = [(String,v)]

But in our case, we can apply the same trick again! We have 'String =
[Char]' and given an implementation of

  data MapChar v = ...

we can use exactly the same code from 'MapPath v' to implement
'MapString v'! (This reuse can be abstracted into a type class, but I'll
not cover that here.) Of course, we need 'MapChar v' now. But yet, again
we can think of Char as

  Char ^= Int ^= [Bool]

where the '[Bool]' means the list of digits in binary representation.
So, given 'MapBool v', we can implement 'MapChar v' with yet again the
same code that we used for the preceding finite maps! Fortunately, the
recursion ends here because a finite map for 'Bool'eans is just the pair

  type MapBool v = (Maybe v, Maybe v)



That's quite beautiful, but I don't actually need to go that far.  Question
though, does taking the approach to this conclusion actually have real
applications?

In case your head does not yet hurt too much :), further information

about tries in Haskell and a detailed explanation of why the code above
works, can be found in.



I did try to write my own insertWithInit called by fromPath (below), which I
couldn't get working.  Branches went missing from the result.  I had so much
trouble figuring where in the function I forgot to do something.

At this point my head was about to explode, so I took a different approach
using union called by fromList' (also below), which from my limited testing
appears to work.  I also find the union function incredibly easy to
understand.  I only hope I got it right.

Thanks much,

-John

import qualified Data.Map as Map
import Data.Map (Map)

type Path k = [k]

data Trie k v = Trie v (Map k (Trie k v)) deriving Show

singleton :: v - Trie k v
singleton v = Trie v Map.empty

insertWithInit :: (Ord k) =
 v - (v - v - v) - Path k - v - Trie k v - Trie k v
insertWithInit _ fInsert [] v (Trie v' m) =
 Trie (fInsert v v') m
insertWithInit fInit fInsert (x:xs) v (Trie v' m) =
 Trie v' (Map.insertWith merge x subTrie m)
 where
   subTrie = insertWithInit fInit fInsert xs v (singleton fInit)
   merge = seq

-- Left biased union
union :: (Ord k) = Trie k v - Trie k v - Trie k v
union (Trie k0 v0) (Trie k1 v1) = Trie k0 v
 where
   v = Map.unionWith union v0 v1

fromPath :: (Ord k) = v - v - Path k - Trie k v
fromPath initV v path = foldr addParent (singleton v) path
 where
   addParent step child = Trie initV (Map.fromList [(step, child)])

fromList :: [Path String] - Trie String ()
fromList paths = foldl f (singleton ()) paths
 where
   f :: Trie String () - Path String - Trie String ()
   f trie path = insertWithInit () (\x y - ()) path () trie

fromList' :: [Path String] - Trie String ()
fromList' paths = foldl f (singleton ()) paths
 where
   f :: Trie String () - Path String - Trie String ()
   f trie path = union trie (fromPath () () path)

prettyPrint :: Trie String () - IO ()
prettyPrint trie = putStrLn $ unlines $ prettyPrint' trie
 where
   prettyPrint' (Trie v m) = Map.foldWithKey f [] m
   f k a out = out ++ [k] ++ (map (  ++) (prettyPrint' a))
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


[Haskell-cafe] Paths to tree

2007-01-29 Thread John Ky

Hi,

I've written some code and was wondering if there was a better way to write
it in terms of readability, brevity and/or efficiency.

The function concerned is pathsToForest which takes a list of paths (ie.
[[String]]) and converts it into a tree structure where the individual nodes
are the names in the path.  Siblings with the same name are merged.

For instance:

 prettyPrint $ mergeForest $ pathsToForest [[a, b, c], [c, b,
a], [a, b, d]]

gives:

 a
  b
   d
   c
 c
  b
   a

Thanks

-John

import Data.Tree
import Control.Monad

data ArcData = ArcData
 { name :: String
 } deriving Show

type ArcTree = Tree ArcData
type ArcForest = Forest ArcData

pathsToForest :: [[String]] - ArcForest
pathsToForest paths = mergeForest $ concat $ map pathToTree paths


mergeForest :: ArcForest - ArcForest
mergeForest [] = []
mergeForest (x:xs) = merge x (mergeForest xs)
 where
   merge :: ArcTree - ArcForest - ArcForest
   merge tree [] = [tree]
   merge tree (y:ys) =
 if sameTreeName tree y
   then
 merge
   tree
   { subForest = mergeForest ((subForest tree) ++ (subForest y))
   }
   ys
   else
 (y:merge tree ys)

treeName :: ArcTree - String
treeName tree = name $ rootLabel $ tree

sameTreeName :: ArcTree - ArcTree - Bool
sameTreeName treeLeft treeRight = treeName treeLeft == treeName treeRight

pathToTree :: [String] - ArcForest
pathToTree [] = []
pathToTree (name:subpath) =
 [ Node
   { rootLabel = ArcData { name = name }
   , subForest = pathToTree subpath
   }
 ]

prettyPrint' :: ArcForest - [String]
prettyPrint' [] = []
prettyPrint' (x:xs) =
 [name $ rootLabel $ x] ++ (map (  ++) (prettyPrint' $ subForest x))
++
 prettyPrint' xs

prettyPrint :: ArcForest - IO ()
prettyPrint forest = do
 forM_ (prettyPrint' forest) putStrLn
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Trouble understanding records and existential types

2007-01-25 Thread John Ky

Let me try this option and see how I go.

Thanks

-John

On 1/25/07, Brandon S. Allbery KF8NH [EMAIL PROTECTED] wrote:


 (b) I think you *can* do this with a class:

 class Node a where
name :: a - String

 data Branch = Branch { brName :: String, ... }
 data Leaf = Leaf { lName :: String, ... }

 instance Node Branch where
name = brName

 instance Node Leaf where
name = lName

 Okay, though it's a lot more wordy.

How so?  You were declaring the class and instances anyway; I simply
defined a new method to go into it and renamed the constructor fields
to obey Haskell's rules, but you will probably be using the class
method so your code won't care about the latter.

--
brandon s. allbery[linux,solaris,freebsd,perl] [EMAIL PROTECTED]
system administrator [openafs,heimdal,too many hats] [EMAIL PROTECTED]
electrical and computer engineering, carnegie mellon universityKF8NH




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


[Haskell-cafe] A function for Maybes

2007-01-25 Thread John Ky

Is there a built-in function that already does this?

foo :: (a - b) - Maybe a - Maybe b
foo f m
 | isNothing m = Nothing
 | otherwise = Just (f (fromJust m))

*Main foo (+2) (Just 3)
Just 5
*Main foo (+2) Nothing
Nothing

If so what is it?

If not, what should I call it?

Thanks

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


Re: [Haskell-cafe] A function for Maybes (RESOLVED)

2007-01-25 Thread John Ky

Thanks

-John

On 1/26/07, Brandon S. Allbery KF8NH [EMAIL PROTECTED] wrote:



On Jan 25, 2007, at 9:15 , John Ky wrote:

 Is there a built-in function that already does this?

 foo :: (a - b) - Maybe a - Maybe b
 foo f m
   | isNothing m = Nothing
   | otherwise = Just (f (fromJust m))

Nothing specific to Maybe, because the more general liftM (over
monads) or fmap (over functors) already does it.

--
brandon s. allbery[linux,solaris,freebsd,perl] [EMAIL PROTECTED]
system administrator [openafs,heimdal,too many hats] [EMAIL PROTECTED]
electrical and computer engineering, carnegie mellon universityKF8NH




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


[Haskell-cafe] Trouble understanding records and existential types

2007-01-24 Thread John Ky

Hi,

A while back I asked about OO programming in Haskell and discovered
existential types.  I understood that existential types allowed me to write
heterogeneous lists which seemed sufficient at the time.

Now trying to combine those ideas with records:

data AnyNode = forall a. Node a = AnyNode a

class Node -- yadda yadda

data Branch = Branch { name :: String, description :: String, children ::
[AnyNode] }
data Leaf = Leaf { name :: String, value :: String }

The problem here is I can't use the same 'name' field for both Branch and
Leaf.  Ideally I'd like the name field in the Node class, but it doesn't
seem that Haskell classes are for that sort of thing.

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


Re: [Haskell-cafe] Trouble understanding records and existential types

2007-01-24 Thread John Ky

On 1/25/07, Brandon S. Allbery KF8NH [EMAIL PROTECTED] wrote:


I'm probably missing something, but:

(a) Why not:

data ANode = Branch { name :: String, description :: String,
children :: [AnyNode] }
| Leaf { name :: String, value :: String } -- this reuse
is legal
-- leaving Node available if you still need it



Would I be able to this?

  getLeaves :: ANode - [Leaf]

If not, is it the case that people generally don't bother and do this
instead?

  getLeaves :: ANode - [ANode]

(b) I think you *can* do this with a class:


class Node a where
   name :: a - String

data Branch = Branch { brName :: String, ... }
data Leaf = Leaf { lName :: String, ... }

instance Node Branch where
   name = brName

instance Node Leaf where
   name = lName



Okay, though it's a lot more wordy.

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


[Haskell-cafe] What does the withProcessHandle_ function do?

2007-01-15 Thread John Ky

I want to learn how to use FFI with Win32, so I'm looking through the GHC
source code.  I encountered the function

terminateProcess :: ProcessHandle - IO ()
terminateProcess ph = do
 withProcessHandle_ ph $ \p_ -
   case p_ of
 ClosedHandle _ - return p_
 OpenHandle h - do
   throwErrnoIfMinus1_ terminateProcess $ c_terminateProcess h
   return p_

which uses withProcessHandle_.  What does it do?

Thanks

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


Re: [Haskell-cafe] UDP client/server

2007-01-11 Thread John Ky

Hi,

What's wrong with my UDP client?

echoClient :: IO ()
echoClient = withSocketsDo $ do
   putStrLn [a]
   sock - socket AF_INET Datagram 0
   putStrLn [b]
   connect sock (SockAddrInet 9900 iNADDR_ANY)
   putStrLn [c]
   n - send sock hi
   putStrLn [d]
   return ()

I get:

*Main echoClient
[a]
[b]
*** Exception: connect: failed (Cannot assign requested address
(WSAEADDRNOTAVAI
L))

Thanks

-John


On 1/12/07, Gregory Wright [EMAIL PROTECTED] wrote:



Hi John,

On Jan 11, 2007, at 10:35 AM, Gregory Wright wrote:


 Hi John,

 On Jan 11, 2007, at 1:58 AM, John Ky wrote:

 Hello,

 Does anyone know where I can find a simple UDP client/server
 written in Haskell?

 Something along the lines of an echo server would do.

 Thanks

 -John


 Try:



snip

For testing, you need only use

gregory-wrights-powerbook-g4-17 nc -ul -p 9900 127.0.0.1

and whatever you type should be echoed.  My original description
of how to test:

 On my OS X/ppc 10.4.8 system, the above builds with ghc 6.6 and if
 I open one
 terminal with

 gregory-wrights-powerbook-g4-17 nc -u 127.0.0.1 9900

 and another with

 gregory-wrights-powerbook-g4-17 nc -ul -p 9900 127.0.0.1

 whatever I type into the first terminal appears on the second.  You
 may have to
 consult your documentation for the options to your version of nc
 (or netcat,
 if you use that instead).

is wrong.  (It will copy from one terminal to the other when the
daemon is not present.)

Best,
Greg


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


Re: [Haskell-cafe] UDP client/server

2007-01-11 Thread John Ky

Nevermind,

I just got the client to work:

echoClient :: IO ()
echoClient = withSocketsDo $ do
   sock - socket AF_INET Datagram 0
   n - sendTo sock hi (SockAddrInet echoPort 0x0107f)
   return ()

Thanks everyone for your help.

-John

On 1/12/07, John Ky [EMAIL PROTECTED]  wrote:Hi,

What's wrong with my UDP client?

echoClient :: IO ()
echoClient = withSocketsDo $ do
   putStrLn [a]
   sock - socket AF_INET Datagram 0
   putStrLn [b]
   connect sock (SockAddrInet 9900 iNADDR_ANY)
   putStrLn [c]
   n - send sock hi
   putStrLn [d]
   return ()

I get:

*Main echoClient
[a]
[b]
*** Exception: connect: failed (Cannot assign requested address
(WSAEADDRNOTAVAI
L))

Thanks

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


[Haskell-cafe] CTRL+C in ghci.exe

2007-01-11 Thread John Ky

Hi,

Is it possible to use CTRL+C or equivalent to interrupt a computation or I/O
and return to the ghci prompt?

Thanks

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


Re: [Haskell-cafe] CTRL+C in ghci.exey

2007-01-11 Thread John Ky

Hi Stefan,

It doesn't work for me.  I'm running GHC 6.6 on Windows XP.  The computation
stops, but I don't get my prompt back.

C:\ghci
  ___ ___ _
 / _ \ /\  /\/ __(_)
/ /_\// /_/ / /  | |  GHC Interactive, version 6.6, for Haskell 98.
/ /_\\/ __  / /___| |  http://www.haskell.org/ghc/
\/\/ /_/\/|_|  Type :? for help.

Loading package base ... linking ... done.
Prelude [1..]
[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,3
0,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,
57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83
,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107
,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127
,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147
,148,149,150,151,152,153,154,155,156,157,158,159,160,161,162,163,164,165,166,167
,168,169,170,171,172,173,174,175,176,177,178,179,180,181,182,183,184,185,186,187
,188,189,190,191,192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207
,208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223,224,225,226,227
,228,229,230,231,232,233,234,235,236,237,238,239,240,241,242,243,244,245,246,247
,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267
,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,283,284,285,286,287
,288,289,290,291,292,293,294,295,296,297,298,299,300,301,302,303,304,305,306,307
,308,309,3

Thanks

-John

On 1/12/07, Stefan O'Rear [EMAIL PROTECTED] wrote:


On Fri, Jan 12, 2007 at 05:07:04PM +1100, John Ky wrote:
 Hi,

 Is it possible to use CTRL+C or equivalent to interrupt a computation or
I/O
 and return to the ghci prompt?

Yes.

[EMAIL PROTECTED]:~/lb-sorear$ ghci
   ___ ___ _
  / _ \ /\  /\/ __(_)
/ /_\// /_/ / /  | |  GHC Interactive, version 6.7, for Haskell 98.
/ /_\\/ __  / /___| |  http://www.haskell.org/ghc/
\/\/ /_/\/|_|  Type :? for help.

Loading package base ... linking ... done.
Prelude [0..]

[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,

32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,

61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,

90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,1

14,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,130,131,132,133,134,135,

136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157

,158,159,160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,17

9,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,2

01,202,203,204,205,206,207,208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,

223,224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239,240,241,242,243,244

,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,26

6,267,268,269,270,271,272,273,274,275,276,277,278,279,280,281,282,283,284,285,286,287,2

88,289,290,291,292,293,294,295,296,297,298,299,300,301,302,303,304,305,306,307,308,309,

310,311,312,313,314,315,316,317,318,319,320,321,322,323,324,325,326,327,328,329,330,331

,332,333,334,335,336,337,338,339,340,341,342,343,344,345,346,347,348,349,350,351,352,35
3,354,355,356,357,358,35Interrupted.
Prelude

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


[Haskell-cafe] UDP client/server

2007-01-10 Thread John Ky

Hello,

Does anyone know where I can find a simple UDP client/server written in
Haskell?

Something along the lines of an echo server would do.

Thanks

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


[Haskell-cafe] Re: Designing an object model in Haskell (RESOLVED)

2006-12-13 Thread John Ky

Hi all,

I'm now using existential types.  I avoided learning about them because the
name sounded so highly technical and obscure it did not occur to me they
could be related to OO.

Thanks,

-John

On 12/7/06, John Ky [EMAIL PROTECTED] wrote:


Hi,

I've got an object model that I have a difficult time conceptualising how
it might look like in Haskell:

class Element { }

class Inline : Element { }

class ParentInline : Inline {
   ListInline children;
}

class Bold : ParentInline { }
class Underline : ParentInline { }

class Link : ParentInline {
   String link;
}

class Text : Inline {
   String text;
}

class Block : Element { }

class Paragraph : Block {
   ListInline paragraph;
}

class Heading : Block {
   ListInline heading;
}

class Document : Element {
   ListBlock blocks;
}

How best to represent this OO data model in Haskell?

Thanks

-John


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


[Haskell-cafe] Designing an object model in Haskell

2006-12-07 Thread John Ky

Hi,

I've got an object model that I have a difficult time conceptualising how it
might look like in Haskell:

class Element { }

class Inline : Element { }

class ParentInline : Inline {
  ListInline children;
}

class Bold : ParentInline { }
class Underline : ParentInline { }

class Link : ParentInline {
  String link;
}

class Text : Inline {
  String text;
}

class Block : Element { }

class Paragraph : Block {
  ListInline paragraph;
}

class Heading : Block {
  ListInline heading;
}

class Document : Element {
  ListBlock blocks;
}

How best to represent this OO data model in Haskell?

Thanks

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


[Haskell-cafe] Testing non-exported functions using ghci

2006-11-13 Thread John Ky
Hello,I have modules that don't export some functions. Is there a way I can access them from ghci without exporting them?Thanks-John
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


[Haskell-cafe] What is the best way to preserve the order of a list

2006-11-01 Thread John Ky
Hi,I have a list of entities. Each entity has a priority field and an order field. The priority field contain the input values to my algorithm, the order fields contain the output value of my algorithm. My algorithm needs to assign 1 to the order field of the entity with the lowest priority value, 2 to the order field of the entity with the next lowest priority value,  and so on. I've written a function orderByPriority that does that. However, it also does something else that is undesireable. It reorders the list.
My question is, how do I preserve the ordering of entities in my list and still be able to assign the proper order values to each entity? Is there an efficient way to do this? How else might I improve my orderByPriority algorithm.
Thanks-John import Data.List data Entity = Entity { entityId :: Int, priority :: Float, order :: Int } initEntity = Entity {
 entityId = 0, priority = 0.0, order = 0 } myList = [ initEntity { entityId = 1, priority = 8.7 }, initEntity { entityId = 2, priority = 5.4
 }, initEntity { entityId = 3, priority = 2.9 }, initEntity { entityId = 4, priority = 5.4 }, initEntity { entityId = 5, priority = 1.3 }, initEntity { entityId = 6, priority = 
3.5 }, initEntity { entityId = 7, priority = 9.5 } ] comparePriority entity1 entity2 = compare (priority entity1) (priority entity2) orderByPriority :: [Entity] - [Entity]
 orderByPriority entities = assignOrder orderList 1 where orderList = sortBy comparePriority entities assignOrder [] _ = [] assignOrder (entity:entities) count = (entity { order = count }):(assignOrder entities (count + 1))
 instance Show Entity where show entity = { ++ entityId: ++ (show $ entityId entity) ++ , ++ priority: ++ (show $ priority entity) ++ , ++
 order:  ++ (show $ order entity) ++ }
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] What is the best way to preserve the order of a list (RESOLVED)

2006-11-01 Thread John Ky
Thanks Stefan,-JohnOn 11/1/06, Stefan Holdermans [EMAIL PROTECTED] wrote:
John, My question is, how do I preserve the ordering of entities in my list and still be able to assign the proper order values to each entity?Is there an efficient way to do this?How else might I
 improve my orderByPriority algorithm.Straightforwardly, you could do it like this: import List (sortBy) type Priority = Int type Order= Int order :: [Priority] - [(Priority, Order)]
 order =unlabel . sortOnLab . assignOrder . sortOnPrio . label where label = zip [0 ..] unlabel = map snd sortOnLab = sortBy (\(l, _) (m, _) - compare l m)
 sortOnPrio= sortBy (\(_, p) (_, q) - compare p q) assignOrder = \xs - zipWith (\(l, p) o - (l, (p, o))) xs [0 ..]For instance:  order [5, 2, 3, 7] [(5,2),(2,0),(3,1),(7,3)]
HTH, Stefan
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


[Haskell-cafe] Re: Best way to write endsWith (RESOLVED)

2006-10-22 Thread John Ky
Hi,Thanks all. I learnt quite a few things:1. There was already an equivalent builtin function.2. That the best function argument order is the least surprising one.3. That I can choose my preferred function order by changing the name of the function.
4. That the most efficient way of doing something in Haskell can be so short.5. Operators really are awesome.-JohnOn 10/22/06, John Ky
 [EMAIL PROTECTED] wrote:Hello,
I have this function here: endsWith :: Eq a = [a] - [a] - Bool endsWith suffix list | lengthDifference  0 = False | otherwise = (drop lengthDifference list) == suffix
 where lengthDifference = (length list) - (length suffix)Would this be the preferred function argument order? Or is the reverse (ie. endsWith list suffix) better?I like being able to say abc `endsWith` c, but I also like to be able to say map (endsWith 't') [cat, dog] but I can't have both.
By the way, is there a better way to write this function to be clearer and more efficient?Thanks-John


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


[Haskell-cafe] Best way to write endsWith

2006-10-21 Thread John Ky
Hello,I have this function here: endsWith :: Eq a = [a] - [a] - Bool endsWith suffix list | lengthDifference  0 = False | otherwise = (drop lengthDifference list) == suffix
 where lengthDifference = (length list) - (length suffix)Would this be the preferred function argument order? Or is the reverse (ie. endsWith list suffix) better?I like being able to say abc `endsWith` c, but I also like to be able to say map (endsWith 't') [cat, dog] but I can't have both.
By the way, is there a better way to write this function to be clearer and more efficient?Thanks-John
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


[Haskell-cafe] Trying to write a TCP proxy

2006-09-20 Thread John Ky

Hello,

I'm trying to use haskell to put together a TCP proxy I can put
between my browser and my webserver.

This is as far as I got.  The webserver isn't returning my request:


listen = withSocketsDo $ do
  putStrLn Listening...
  socket - listenOn $ PortNumber 8082
  (handleToClient, hostName, portNumber) - accept socket
  putStrLn Connected to client
  contents - hGetContents handleToClient
  putStrLn Received from client:
  putStrLn contents
  handleToServer - connectTo 127.0.0.1 (PortNumber 8080)
  putStrLn Connected to server
  hPutStrLn handleToServer contents
  putStrLn Waiting for server to respond
  hPutStrLn handleToServer \r\n\r\n
  putStrLn Waiting for server to respond
  result - hGetContents handleToServer
  putStrLn result
  hClose handleToServer
  hClose handleToClient
  sClose socket


Am I doing something wrong?

Thanks,

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


[Haskell-cafe] Re: Trying to write a TCP proxy

2006-09-20 Thread John Ky

Actually, it blocks on:


   putStrLn contents


It even blocks if I replace it with:


   print $ length contents


Is there some kind of magic happening here?

-John

On 9/20/06, John Ky [EMAIL PROTECTED] wrote:

Hello,

I'm trying to use haskell to put together a TCP proxy I can put
between my browser and my webserver.

This is as far as I got.  The webserver isn't returning my request:

 listen = withSocketsDo $ do
   putStrLn Listening...
   socket - listenOn $ PortNumber 8082
   (handleToClient, hostName, portNumber) - accept socket
   putStrLn Connected to client
   contents - hGetContents handleToClient
   putStrLn Received from client:
   putStrLn contents
   handleToServer - connectTo 127.0.0.1 (PortNumber 8080)
   putStrLn Connected to server
   hPutStrLn handleToServer contents
   putStrLn Waiting for server to respond
   hPutStrLn handleToServer \r\n\r\n
   putStrLn Waiting for server to respond
   result - hGetContents handleToServer
   putStrLn result
   hClose handleToServer
   hClose handleToClient
   sClose socket

Am I doing something wrong?

Thanks,

-John


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


Re: [Haskell-cafe] Trying to write a TCP proxy

2006-09-20 Thread John Ky

Hi Bulat,

Thanks.  Yes it helps with an earlier implementation I wrote (below).
But surely there must be a better way to write this.  My code is way
to verbose.

-John

---


doProxyServer handleToClient handleToServer = do
  eof - hIsEOF handleToServer
  if not eof
then do
  ready - hReady handleToServer
  if ready
then do
  text - hGetChar handleToServer
  putChar text
  hPutChar handleToClient text
  doProxyServer handleToClient handleToServer
else do
  hPutStr handleToClient \n
  doProxyClient handleToClient handleToServer
else do
  hClose handleToServer
  hClose handleToClient



doProxyClient handleToClient handleToServer = do
  ready - hReady handleToClient
  if ready
then do
  text - hGetChar handleToClient
  putChar text
  hPutChar handleToServer text
  doProxyClient handleToClient handleToServer
else do
  hPutStr handleToServer \n
  doProxyServer handleToClient handleToServer



listen = withSocketsDo $ do
  putStrLn Listening...
  socket - listenOn $ PortNumber 8082
  (handleToClient, hostName, portNumber) - accept socket
  putStrLn Connected to client
  handleToServer - connectTo localhost (PortNumber 8080)
  hSetBuffering handleToServer LineBuffering
  putStrLn Connected to server
  doProxyClient handleToClient handleToServer
  hClose handleToServer
  putStrLn Closed server
  hClose handleToClient
  putStrLn Closed client
  sClose socket



main = listen



On 9/20/06, Bulat Ziganshin [EMAIL PROTECTED] wrote:

Hello John,

Wednesday, September 20, 2006, 3:59:36 PM, you wrote:

 I'm trying to use haskell to put together a TCP proxy I can put
 between my browser and my webserver.

 This is as far as I got.  The webserver isn't returning my request:

hSetBuffering handleToServer LineBuffering

may help


--
Best regards,
 Bulatmailto:[EMAIL PROTECTED]



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


Re: [Haskell-cafe] Re: Trying to write a TCP proxy

2006-09-20 Thread John Ky

Hi again,

Given that putStrLn contents did manage to print out the HTTP header
before blocking, am I correct in coming to the conlusion that
'contents' is evaluated lazily?  So Monads don't actually eliminate
laziness?

-John

On 9/20/06, Philippa Cowderoy [EMAIL PROTECTED] wrote:

On Wed, 20 Sep 2006, John Ky wrote:

 Actually, it blocks on:

 putStrLn contents

 It even blocks if I replace it with:

 print $ length contents

 Is there some kind of magic happening here?


No, but you're trying to do magic - it can't get all of contents until the
connection's dropped.

--
[EMAIL PROTECTED]

A problem that's all in your head is still a problem.
Brain damage is but one form of mind damage.


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