[Haskell-cafe] IterIO: How to write use my inumReverse
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
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
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
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
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?
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?
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?
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
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
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
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
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?
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?
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?
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?
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?
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?
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?
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?
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
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
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)
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
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
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
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
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
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
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
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
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?
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?
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
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
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?
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?
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
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
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
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
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
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?
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
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
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
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?
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
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?
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?
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?
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)
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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)
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
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
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?
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
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
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
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
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
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)
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
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
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
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)
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)
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
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
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
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
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
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