[Haskell-cafe] Some reflections on Haskell
https://plus.google.com/u/0/111705054912446689620/posts/DPdA2rUSQ6c Comments are welcome! Kevin ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] Adding state to a library
I have a library of functions that all take cfg parameter (and usually others) and return results in the IO monad. It is sometimes useful to drop the config parameter by using a state-like monad.. I have found that I can wrap all my functions like so: withLibrary cfg f = f cfg stateF a b c d = ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Adding state to a library
My apologies. My last message was sent prematurely. I have a library of functions that all take a config parameter (and usually others) and return results in the IO monad. It is sometimes useful to drop the config parameter by using a state-like monad.. I have found that I can wrap all my functions like so: withLibrary cfg f = f cfg stateF a b c d = getConfig = \cfg - liftIO $ withLibrary cfg libraryF a b c d notice that I need stateF and libraryF lines, each with n parameters. Upgrading my library like this is rather tedious. I would prefer to just write something like stateF = upgrade libraryF but I can find no way to define the function upgrade in Haskell. This must be a fairly common problem. Is there a simple solution? On Sun, Dec 18, 2011 at 10:20 PM, Kevin Jardine kevinjard...@gmail.comwrote: I have a library of functions that all take cfg parameter (and usually others) and return results in the IO monad. It is sometimes useful to drop the config parameter by using a state-like monad.. I have found that I can wrap all my functions like so: withLibrary cfg f = f cfg stateF a b c d = ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Adding state to a library
By upgrading, I meant move a function from an IO monad with a config parameter to a state monad without one. On Dec 18, 10:52 pm, Bas van Dijk v.dijk@gmail.com wrote: On 18 December 2011 22:26, Kevin Jardine kevinjard...@gmail.com wrote: I have a library of functions that all take a config parameter (and usually others) and return results in the IO monad. It is sometimes useful to drop the config parameter by using a state-like monad.. If you're not modifying the configuration, a reader monad transformer is probably enough: http://hackage.haskell.org/packages/archive/transformers/0.2.2.0/doc/... You probably want to define your own monad transformer for your library: newtype MyMonad m a = M {unM :: ReaderT Config m a} deriving (Functor, Applicative, Monad, MonadTrans, MonadIO) getConfig :: MyMonad m Config getConfig = M ask I have found that I can wrap all my functions like so: withLibrary cfg f = f cfg This can now be defined as: withLibrary :: Config - MyMonad m a - m a withLibrary cfg m = runReaderT (unM m) cfg stateF a b c d = getConfig = \cfg - liftIO $ withLibrary cfg libraryF a b c d notice that I need stateF and libraryF lines, each with n parameters. Upgrading my library like this is rather tedious. I would prefer to just write something like stateF = upgrade libraryF but I can find no way to define the function upgrade in Haskell. This must be a fairly common problem. Is there a simple solution? What do you mean by upgrading? Cheers, Bas ___ Haskell-Cafe mailing list Haskell-C...@haskell.orghttp://www.haskell.org/mailman/listinfo/haskell-cafe ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] Cabal issue
I understand that this may have been addressed before on this list in some form, so I'll be brief: Had problem with deprecated package, was told my only option was to wipe my Haskell install and start over. Is this true and if so, doesn't this mean that Cabal (or the package management system that it is a part of) is broken? Details here: https://plus.google.com/u/0/111705054912446689620/posts/V1186HGWEap Kevin ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] Haskell vs. Dart
After Google's disappointing Dart announcement yesterday, I decided to tweak them a bit and mention Haskell and functional programming languages as an alternative: https://plus.google.com/u/0/111705054912446689620/posts/UcyLBH7RLXs Comments on the post are welcome! ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] YesodAuth documentation
When I review the original post I see only a question: Does passwords stored in a database in an unencrypted form? rather than a request. So I'm not sure that was the intent. I'm amazed that anyone (Sony!!!?) would store unencrypted passwords of course. Kevin On Jun 14, 10:21 am, cheater cheater cheate...@gmail.com wrote: I am surprised out of the whole list no one has stormed down on Nikita for wanting to store passwords as plain text. Nikita: never store passwords in plain text. Ever. D. On Mon, Jun 13, 2011 at 09:34, Никита Тимофеев ndtimof...@gmail.com wrote: Does exist some simple examples using yesod authentication except code of Haskellers site? Does exist some examples using YesodAuthEmail? For example, can i use third-party mail server instead of Sendmail for YesodAuthEmail? Can i disable registration confirmation? Does passwords stored in a database in an unencrypted form? -- Timofeev N.D. ___ Haskell-Cafe mailing list haskell-c...@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe ___ Haskell-Cafe mailing list Haskell-C...@haskell.orghttp://www.haskell.org/mailman/listinfo/haskell-cafe ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] Re: dynamic loading of code on windows
/unsafeio/Unsafe.conf config.status: creating config.h Preprocessing library plugins-1.5.1.4... Building plugins-1.5.1.4... [ 1 of 12] Compiling System.Plugins.Process ( src\System\Plugins\Process.hs, dis t\build\System\Plugins\Process.o ) [ 2 of 12] Compiling System.Plugins.Parser ( src\System\Plugins\Parser.hs, dist\ build\System\Plugins\Parser.o ) [ 3 of 12] Compiling System.Plugins.LoadTypes ( src\System\Plugins\LoadTypes.hs, dist\build\System\Plugins\LoadTypes.o ) [ 4 of 12] Compiling System.Plugins.Consts ( src\System\Plugins\Consts.hs, dist\ build\System\Plugins\Consts.o ) src\System\Plugins\Consts.hs:39:22: lexical error in string/character literal at character 'P' cabal.exe: Error: some packages failed to install: plugins-1.5.1.4 failed during the building phase. The exception was: ExitFailure 1 Any clues? Should I try to use latest source tree? I am really interested in the plugins approach, rather than the interpreter approach. What I am trying to achieve is a system similar to Yi as presented in Don Stewart's paper (http://www.cse.unsw.edu.au/~dons/papers/yi.pdf), but much simpler, of course. The system would load modules as found in some known location, run tests found here before really accepting them, then use them, with the possibility of replacing those modules when a newer version is found. The idea is to provide a self-tested and continuously running system for development, something that might be reminiscent of Smalltalk although I never programmed in Smalltalk. Thanks in advance for advises, REgards, Arnaud On Fri, Nov 12, 2010 at 8:49 PM, Alberto G. Corona agocor...@gmail.com wrote: I use Hint for the same purpose. It has been tested under windows 2010/11/12 Arnaud Bailly arnaud.oq...@gmail.com Hello Kevin, Thanks. I understand that this is a toolchain issue, I just got used to the nice feeling of having 'cabal install foo' works seamlessly and flawlessly to get me some magic piece of software :-) I will try to be more patient and try to setup a proper toolchain for installing plugins package. Arnaud On Fri, Nov 12, 2010 at 7:01 PM, Kevin Jardine kevinjard...@gmail.com wrote: This isn't about the plugin functionality, it's about compiling code. As the message says : This requires a Unix compatibility toolchain such as MinGW+MSYS or Cygwin. You'll find that you need such a toolchain to compile much open source software, including many Haskell modules, on Windows. Personally I use MinGW+MSYS on my Windows machine. It works very well. Kevin On Nov 12, 3:20 pm, Arnaud Bailly arnaud.oq...@gmail.com wrote: Hello, I recently tried to cabal install plugins on a windows box and it failed with the following error: Resolving dependencies... Downloading plugins-1.5.1.4... Configuring plugins-1.5.1.4... cabal: The package has a './configure' script. This requires a Unix compatibility toolchain such as MinGW+MSYS or Cygwin. cabal: Error: some packages failed to install: plugins-1.5.1.4 failed during the configure step. The exception was: ExitFailure 1 What solution can I use to load dynamically code in a cross-platform way ? Thanks in advance Arnaud ___ Haskell-Cafe mailing list haskell-c...@haskell.orghttp://www.haskell.org/mailman/listinfo/haskell-cafe ___ Haskell-Cafe mailing list haskell-c...@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe ___ Haskell-Cafe mailing list haskell-c...@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe ___ Haskell-Cafe mailing list haskell-c...@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe ___ Haskell-Cafe mailing list haskell-c...@haskell.orghttp://www.haskell.org/mailman/listinfo/haskell-cafe ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] Re: dynamic loading of code on windows
This isn't about the plugin functionality, it's about compiling code. As the message says : This requires a Unix compatibility toolchain such as MinGW+MSYS or Cygwin. You'll find that you need such a toolchain to compile much open source software, including many Haskell modules, on Windows. Personally I use MinGW+MSYS on my Windows machine. It works very well. Kevin On Nov 12, 3:20 pm, Arnaud Bailly arnaud.oq...@gmail.com wrote: Hello, I recently tried to cabal install plugins on a windows box and it failed with the following error: Resolving dependencies... Downloading plugins-1.5.1.4... Configuring plugins-1.5.1.4... cabal: The package has a './configure' script. This requires a Unix compatibility toolchain such as MinGW+MSYS or Cygwin. cabal: Error: some packages failed to install: plugins-1.5.1.4 failed during the configure step. The exception was: ExitFailure 1 What solution can I use to load dynamically code in a cross-platform way ? Thanks in advance Arnaud ___ Haskell-Cafe mailing list haskell-c...@haskell.orghttp://www.haskell.org/mailman/listinfo/haskell-cafe ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] Re: Red links in the new haskell theme
To be fair to the Haddock designer, red links are common these days. Here's two examples (among many): http://www.bbc.co.uk/ http://www.slate.com/ In the second case the site uses blue, black *and* red links to distinguish different types of content. They are all in bold and underline when hovered over so are not hard to distinguish from ordinary text. Kevin. On Oct 28, 9:52 am, Michael Snoyman mich...@snoyman.com wrote: On Thu, Oct 28, 2010 at 9:50 AM, Christopher Done chrisd...@googlemail.com wrote: On 28 October 2010 03:41, Victor Oliveira rhapso...@gmail.com wrote: Hi Cafe, I really liked the new colors of haskell theme, but... Is really red a good color for links? At least for me, red links looks like broken or already visited ones. And the worst is hackage docs. It is really eye tiring to read. It's just a thought. Maybe it just with me. What about you? This was my initial impression. Red means broken. Links are blue. I thought maybe no one would be bothered by it, but I see one person at least. I'm not incredibly bothered by it, but I did find it a bit strange. Michael ___ Haskell-Cafe mailing list haskell-c...@haskell.orghttp://www.haskell.org/mailman/listinfo/haskell-cafe ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] Re: Should Yesod.Mail be a separate package?
Hi Michael, Last time I checked Hackage for email libraries I could find some basic SMTP systems but nothing very recent or robust. Practically every web app needs to send email, so I think that a robust and well maintained email package would be very useful. I know you have many other projects going at the minute, but if you had a chance to create a stand alone email package, I'd be interested in trying it out. I've been working on a web app engine that combines Heist from Snap and several of the WAI packages with an object store system I've developed myself (and will release on Hackage at some point). Email was a missing piece and it sounds like your package could fill the gap nicely. Kevin On Oct 17, 8:11 am, Michael Snoyman mich...@snoyman.com wrote: Hey all, I wrote a simple email module in Yesod[1] that handles such things as multipart messages and Base64 encoding. It's still missing some features (multipart/alternative, for instance), but it can be useful for throwing together emails. It's currently part of the yesod package, but I'm going to be moving it to a separate package to free me up to make breaking API changes more frequently. As of right now, I'm just going to move it into the yesod-auth package (also being split off from the main yesod package), and therefore it will still have all the dependencies on Yesod. My question is whether people would find this package useful outside the scope of Yesod. There are no dependencies from this module onto any Yesod-specific stuff, so this separation could easily be done. I just don't feel like adding another package to maintain if no one is interested. So if anyone wants this offered up as a separate package, and/or has any API suggestions, please let me know. Michael [1]http://hackage.haskell.org/packages/archive/yesod/0.5.4/doc/html/Yeso... ___ Haskell-Cafe mailing list haskell-c...@haskell.orghttp://www.haskell.org/mailman/listinfo/haskell-cafe ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] Re: Should Yesod.Mail be a separate package?
Hi Robert, I did look at HaskellNet a few months ago. It looked big and undocumented so I guess I got scared away. What I'd be interested in is something with the simplicity of the PHP mail command (or perhaps the phpmailer package). I dislike PHP as a programming language but it does basic web functions like outgoing email fairly well. Perhaps HaskellNet just needs more documentation and examples? Kevin On Oct 17, 10:05 am, Robert Wills wrwi...@gmail.com wrote: Last summer I put cabalized HaskellNet (written by Jun Mukai for a GSOC) (http://hackage.haskell.org/package/HaskellNet) and uploaded it to hackage. I put myself down as a maintainer but I haven't done much maintaining. HaskellNet also does multipart mime and base64 stuff as well as imap and pop access. I haven't looked at Michael's package yet -- I'll have a look this morning to compare. I've been meaning to add try to tls support to HaskellNet. I don't have any huge attachment to HaskellNet so I'd be happy to just help to migrate the useful bits of it to some larger official email package. -Rob On Sun, Oct 17, 2010 at 8:32 AM, Kevin Jardine kevinjard...@gmail.com wrote: Hi Michael, Last time I checked Hackage for email libraries I could find some basic SMTP systems but nothing very recent or robust. Practically every web app needs to send email, so I think that a robust and well maintained email package would be very useful. I know you have many other projects going at the minute, but if you had a chance to create a stand alone email package, I'd be interested in trying it out. I've been working on a web app engine that combines Heist from Snap and several of the WAI packages with an object store system I've developed myself (and will release on Hackage at some point). Email was a missing piece and it sounds like your package could fill the gap nicely. Kevin On Oct 17, 8:11 am, Michael Snoyman mich...@snoyman.com wrote: Hey all, I wrote a simple email module in Yesod[1] that handles such things as multipart messages and Base64 encoding. It's still missing some features (multipart/alternative, for instance), but it can be useful for throwing together emails. It's currently part of the yesod package, but I'm going to be moving it to a separate package to free me up to make breaking API changes more frequently. As of right now, I'm just going to move it into the yesod-auth package (also being split off from the main yesod package), and therefore it will still have all the dependencies on Yesod. My question is whether people would find this package useful outside the scope of Yesod. There are no dependencies from this module onto any Yesod-specific stuff, so this separation could easily be done. I just don't feel like adding another package to maintain if no one is interested. So if anyone wants this offered up as a separate package, and/or has any API suggestions, please let me know. Michael [1]http://hackage.haskell.org/packages/archive/yesod/0.5.4/doc/html/Yeso... ___ Haskell-Cafe mailing list haskell-c...@haskell.orghttp://www.haskell.org/mailman/listinfo/haskell-cafe ___ Haskell-Cafe mailing list haskell-c...@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe ___ Haskell-Cafe mailing list haskell-c...@haskell.orghttp://www.haskell.org/mailman/listinfo/haskell-cafe ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] Re: Should Yesod.Mail be a separate package?
Something along the lines of these examples would be helpful I think: http://phpmailer.worxware.com/index.php?pg=examples Phpmailer is probably the most widely used email library, so if it could be shown that there was a Haskell equivalent (or better), I think that might start attracting the attention of web developers. Kevin On Oct 17, 11:13 am, Robert Wills wrwi...@gmail.com wrote: Yes you're right Kevin. I'll put up a new release sometime in the next week with some more examples and possible some simpler methods if only so HaskellNet can be more easily evaluated. As I recall Happstack also uses an smtp library. I forget which one. -Rob On Sun, Oct 17, 2010 at 9:29 AM, Kevin Jardine kevinjard...@gmail.com wrote: Hi Robert, I did look at HaskellNet a few months ago. It looked big and undocumented so I guess I got scared away. What I'd be interested in is something with the simplicity of the PHP mail command (or perhaps the phpmailer package). I dislike PHP as a programming language but it does basic web functions like outgoing email fairly well. Perhaps HaskellNet just needs more documentation and examples? Kevin On Oct 17, 10:05 am, Robert Wills wrwi...@gmail.com wrote: Last summer I put cabalized HaskellNet (written by Jun Mukai for a GSOC) (http://hackage.haskell.org/package/HaskellNet) and uploaded it to hackage. I put myself down as a maintainer but I haven't done much maintaining. HaskellNet also does multipart mime and base64 stuff as well as imap and pop access. I haven't looked at Michael's package yet -- I'll have a look this morning to compare. I've been meaning to add try to tls support to HaskellNet. I don't have any huge attachment to HaskellNet so I'd be happy to just help to migrate the useful bits of it to some larger official email package. -Rob On Sun, Oct 17, 2010 at 8:32 AM, Kevin Jardine kevinjard...@gmail.com wrote: Hi Michael, Last time I checked Hackage for email libraries I could find some basic SMTP systems but nothing very recent or robust. Practically every web app needs to send email, so I think that a robust and well maintained email package would be very useful. I know you have many other projects going at the minute, but if you had a chance to create a stand alone email package, I'd be interested in trying it out. I've been working on a web app engine that combines Heist from Snap and several of the WAI packages with an object store system I've developed myself (and will release on Hackage at some point). Email was a missing piece and it sounds like your package could fill the gap nicely. Kevin On Oct 17, 8:11 am, Michael Snoyman mich...@snoyman.com wrote: Hey all, I wrote a simple email module in Yesod[1] that handles such things as multipart messages and Base64 encoding. It's still missing some features (multipart/alternative, for instance), but it can be useful for throwing together emails. It's currently part of the yesod package, but I'm going to be moving it to a separate package to free me up to make breaking API changes more frequently. As of right now, I'm just going to move it into the yesod-auth package (also being split off from the main yesod package), and therefore it will still have all the dependencies on Yesod. My question is whether people would find this package useful outside the scope of Yesod. There are no dependencies from this module onto any Yesod-specific stuff, so this separation could easily be done. I just don't feel like adding another package to maintain if no one is interested. So if anyone wants this offered up as a separate package, and/or has any API suggestions, please let me know. Michael [1]http://hackage.haskell.org/packages/archive/yesod/0.5.4/doc/html/Yeso... ___ Haskell-Cafe mailing list haskell-c...@haskell.orghttp://www.haskell.org/mailman/listinfo/haskell-cafe ___ Haskell-Cafe mailing list haskell-c...@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe ___ Haskell-Cafe mailing list haskell-c...@haskell.orghttp://www.haskell.org/mailman/listinfo/haskell-cafe ___ Haskell-Cafe mailing list haskell-c...@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe ___ Haskell-Cafe mailing list haskell-c...@haskell.orghttp://www.haskell.org/mailman/listinfo/haskell-cafe ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] Re: Increasing number of parameters
Jacek, I haven't been following this thread in any detail, so I apologise if I misunderstand your goal, but the ctm function in the polyToMonoid library (which maps its parameters to any specified monoid) appears to work in just this way. It keeps consuming parameters until you hand it to the trm function to deliver the final result. More documentation here: http://hackage.haskell.org/packages/archive/polyToMonoid/0.1/doc/html/Data-PolyToMonoid.html Kevin On Oct 15, 11:38 am, Jacek Generowicz jacek.generow...@cern.ch wrote: Thanks Brandon! I really like the addParam utility, value val prompt = Question prompt (show val) (readCheck val) addParam :: (Show a) = (funTy - String - qty) - (a - funTy) - String - (a - qty) addParam qmakr fun string v = qmakr (fun v) (string++ ++show v) prefix1 = addParam value prefix2 = addParam prefix1 prefix3 = addParam prefix2 but my crusty and sleep-deprived brain is not really grokking the internal plumbing. So I'm trying to get to grips with a simpler variation on the same theme, and I'm still failing. I'm trying to write something along the lines of addArg :: nArgFn - a - nPlus1ArgFn addArg fn a = (a+) fn where = something which applies its right parameter to however many arguments it needs and feeds the result to the left parameter in order to allow me to say sum2 = (+) sum3 = addArg sum2 sum4 = addArg sum3 etc. ___ Haskell-Cafe mailing list haskell-c...@haskell.orghttp://www.haskell.org/mailman/listinfo/haskell-cafe ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] ANNOUNCE: polyToMonoid
Polyvariadic functions that accept an indefinite number of possibly multiple typed arguments are often useful but a bit difficult to declare in Haskell. With some crucial assistance from Oleg Kiselyov, I have created a library that supplies two very general polyvariadic functions that can map their arguments into any monoid you specify. All you need to do to use these is to specify the monoid and some instances of a toMonoid function to map all the types you want to pass as arguments into the monoid. The functions can act as a sort of generalised list, but of course there are also many interesting monoids which are not lists. The library is now up on Hackage here: http://hackage.haskell.org/package/polyToMonoid-0.1 along with detailed documentation and a few examples here: http://hackage.haskell.org/packages/archive/polyToMonoid/0.1/doc/html/Data-PolyToMonoid.html As you can see, the code is short and depends only upon the GHC base library. The original thread discussing the polyToMonoid idea is here: http://groups.google.com/group/haskell-cafe/browse_thread/thread/737c6cf921b99e85 Comments and suggestions for improvement are welcome! Kevin ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] Re: Polyvariadic functions operating with a monoid
I have turned the code into a library and put it up on github here: http://github.com/kevinjardine/polyToMonoid The library includes two versions of the function: ptm does not require a termination function but does not allow partial evaluation either. ctm is more composable (returning a function that consumes the next parameter) and requires a termination function trm to return the result. The source includes thorough Haddock friendly comments with examples. My plan is to upload it to Hackage later this week but I wondered if anyone had any comments before I do. Kevin On Oct 11, 11:08 am, Kevin Jardine kevinjard...@gmail.com wrote: It also appears that we need type families to reconstruct the original Haskell list system using polyToMonoid. instance (a ~ a') = Monoidable a [a'] where toMonoid a = [a] testList = putStrLn $ show $ polyToMonoid (mempty :: [a]) a b c Given this instance of Monoidable, you can put any number of values after polyToMonoid (mempty :: [a]) as long as they are exactly the same type. In other words, this acts exactly like the usual Haskell list, going back to my original point that polyToMonoid is a sort of generalised list or a function that takes a bunch of values that can be stuck together in some way. I am a bit surprised that the (a ~ a') is needed, but Haskell will not compile this code with the more usual instance Monoidable a [a] where toMonoid a = [a] Kevin On Oct 11, 9:54 am, Kevin Jardine kevinjard...@gmail.com wrote: Hi Oleg, I've found that if I also add two other slightly scary sounding extensions: OverlappingInstances and IncoherentInstances, then I can eliminate the unwrap function *and* use your type families trick to avoid the outer type annotation. My latest code is here: {-# LANGUAGE TypeSynonymInstances, FlexibleInstances, MultiParamTypeClasses, TypeFamilies #-} {-# LANGUAGE OverlappingInstances, IncoherentInstances #-} module PolyTest where import Data.Monoid class Monoid m = Monoidable a m where toMonoid :: a - m squish :: Monoidable a m = m - a - m squish m a = (m `mappend` (toMonoid a)) class Monoid m = PolyVariadic m r where polyToMonoid :: m - r instance (Monoid m', m' ~ m) = PolyVariadic m m' where polyToMonoid acc = acc instance (Monoidable a m, PolyVariadic m r) = PolyVariadic m (a-r) where polyToMonoid acc = \a - polyToMonoid (squish acc a) Here are three examples. The resulting notation is short enough now that I am no longer tempted to use CPP. All you need to do is to specify the type for mempty. And even this can be skipped if you want to put in the specific mempty value (although I think that the type annotation is often better if slightly longer as it documents clearly what monoid the result is being mapped into). -- [String] example instance Show a = Monoidable a [String] where toMonoid a = [show a] testStringList = putStrLn $ show $ polyToMonoid (mempty :: [String]) True () (Just (5::Int)) -- String example instance Show a = Monoidable a String where toMonoid a = show a testString = putStrLn $ polyToMonoid (mempty :: String) True () (Just (5::Int)) -- product example instance Monoid Double where mappend = (*) mempty = (1.0) :: Double instance Monoidable Int Double where toMonoid = fromIntegral instance Monoidable Double Double where toMonoid = id testProduct = putStrLn $ show $ polyToMonoid (mempty :: Double) (5 :: Int) (2.3 :: Double) (3 :: Int) (8 :: Int) main = do testStringList testString testProduct $ runhaskell PolyTest.hs [True,(),Just 5] True()Just 5 276.0 Kevin On Oct 11, 2:39 am, o...@okmij.org wrote: Sorry, I'm still catching up. I'm replying to first few messages. instance Show a = Monoidable a [String] where toMonoid a = [show a] main = putStrLn $ unwrap $ polyToMonoid [] True () (Just (5::Int)) fails to compile. The error message points to the first problem: No instances for (Monoidable Bool [a], Monoidable () [a], ... The presence of the type variable 'a' means that the type checker doesn't know list of what elements you want (in other words, the context is not specific enough to instantiate the type variable a). Thus, we need to explicitly tell that we wish a list of strings: test3 = putStrLn $ unwrap $polyToMonoid ([]::[String]) True () (Just (5::Int)) Now we get a different error, which points to the real problem this time: the expression `unwrap ' appears as an argument to putStrLn. That means that we are required to produce a String as a monoid. Yet we specified ([]::[String]) as mempty, which is unsuitable as mempty for the String monoid. If we desire the [String] monoid as the result, we need to change the context. For example, test3 = mapM_
[Haskell-cafe] Re: Polyvariadic functions operating with a monoid
Hi Oleg, I've found that if I also add two other slightly scary sounding extensions: OverlappingInstances and IncoherentInstances, then I can eliminate the unwrap function *and* use your type families trick to avoid the outer type annotation. My latest code is here: {-# LANGUAGE TypeSynonymInstances, FlexibleInstances, MultiParamTypeClasses, TypeFamilies #-} {-# LANGUAGE OverlappingInstances, IncoherentInstances #-} module PolyTest where import Data.Monoid class Monoid m = Monoidable a m where toMonoid :: a - m squish :: Monoidable a m = m - a - m squish m a = (m `mappend` (toMonoid a)) class Monoid m = PolyVariadic m r where polyToMonoid :: m - r instance (Monoid m', m' ~ m) = PolyVariadic m m' where polyToMonoid acc = acc instance (Monoidable a m, PolyVariadic m r) = PolyVariadic m (a-r) where polyToMonoid acc = \a - polyToMonoid (squish acc a) Here are three examples. The resulting notation is short enough now that I am no longer tempted to use CPP. All you need to do is to specify the type for mempty. And even this can be skipped if you want to put in the specific mempty value (although I think that the type annotation is often better if slightly longer as it documents clearly what monoid the result is being mapped into). -- [String] example instance Show a = Monoidable a [String] where toMonoid a = [show a] testStringList = putStrLn $ show $ polyToMonoid (mempty :: [String]) True () (Just (5::Int)) -- String example instance Show a = Monoidable a String where toMonoid a = show a testString = putStrLn $ polyToMonoid (mempty :: String) True () (Just (5::Int)) -- product example instance Monoid Double where mappend = (*) mempty = (1.0) :: Double instance Monoidable Int Double where toMonoid = fromIntegral instance Monoidable Double Double where toMonoid = id testProduct = putStrLn $ show $ polyToMonoid (mempty :: Double) (5 :: Int) (2.3 :: Double) (3 :: Int) (8 :: Int) main = do testStringList testString testProduct $ runhaskell PolyTest.hs [True,(),Just 5] True()Just 5 276.0 Kevin On Oct 11, 2:39 am, o...@okmij.org wrote: Sorry, I'm still catching up. I'm replying to first few messages. instance Show a = Monoidable a [String] where toMonoid a = [show a] main = putStrLn $ unwrap $ polyToMonoid [] True () (Just (5::Int)) fails to compile. The error message points to the first problem: No instances for (Monoidable Bool [a], Monoidable () [a], ... The presence of the type variable 'a' means that the type checker doesn't know list of what elements you want (in other words, the context is not specific enough to instantiate the type variable a). Thus, we need to explicitly tell that we wish a list of strings: test3 = putStrLn $ unwrap $polyToMonoid ([]::[String]) True () (Just (5::Int)) Now we get a different error, which points to the real problem this time: the expression `unwrap ' appears as an argument to putStrLn. That means that we are required to produce a String as a monoid. Yet we specified ([]::[String]) as mempty, which is unsuitable as mempty for the String monoid. If we desire the [String] monoid as the result, we need to change the context. For example, test3 = mapM_ putStrLn $ unwrap $ polyToMonoid ([]::[String]) True () (Just (5::Int)) Another example that also fails to compile (but I cannot see why): main = putStrLn $ show $ unwrap $ polyToMonoid (0::Int) (1::Int) (2::Int) (3::Int) No instance for (PolyVariadic Int (WMonoid m)) arising from a use of `polyToMonoid' The error message is informative, mentioning the type variable, m. Whenever that happens, we know that we put a bounded polymorphic expression in the context that is not specific enough. We need some type annotations. In our case, the function 'show' can show values of many types. The type checker does not know that we wish an Int monoid specifically. So, we have to specialize the show function: test4 = putStrLn $ (show :: Int - String) $ unwrap $ polyToMonoid (0::Int) (1::Int) (2::Int) (3::Int) At this point one may wonder if this is all worth it. There are too many annotations. Fortunately, if you are not afraid of one more extension, the annotations can be avoided. Your example would be accepted as it was written, see test3 and test4 below. {-# LANGUAGE TypeSynonymInstances #-} {-# LANGUAGE MultiParamTypeClasses, FlexibleInstances, TypeFamilies #-} module M where import Data.Monoid newtype WMonoid m = WMonoid{unwrap :: m} class Monoid m = Monoidable a m where toMonoid :: a - m class Monoid m = PolyVariadic m p where polyToMonoid :: m - p instance (Monoid m', m' ~ m) = PolyVariadic m (WMonoid m') where polyToMonoid acc = WMonoid acc instance (Monoidable a m, PolyVariadic m r) = PolyVariadic m (a-r) where polyToMonoid acc = \a - polyToMonoid (acc
[Haskell-cafe] Re: Polyvariadic functions operating with a monoid
It also appears that we need type families to reconstruct the original Haskell list system using polyToMonoid. instance (a ~ a') = Monoidable a [a'] where toMonoid a = [a] testList = putStrLn $ show $ polyToMonoid (mempty :: [a]) a b c Given this instance of Monoidable, you can put any number of values after polyToMonoid (mempty :: [a]) as long as they are exactly the same type. In other words, this acts exactly like the usual Haskell list, going back to my original point that polyToMonoid is a sort of generalised list or a function that takes a bunch of values that can be stuck together in some way. I am a bit surprised that the (a ~ a') is needed, but Haskell will not compile this code with the more usual instance Monoidable a [a] where toMonoid a = [a] Kevin On Oct 11, 9:54 am, Kevin Jardine kevinjard...@gmail.com wrote: Hi Oleg, I've found that if I also add two other slightly scary sounding extensions: OverlappingInstances and IncoherentInstances, then I can eliminate the unwrap function *and* use your type families trick to avoid the outer type annotation. My latest code is here: {-# LANGUAGE TypeSynonymInstances, FlexibleInstances, MultiParamTypeClasses, TypeFamilies #-} {-# LANGUAGE OverlappingInstances, IncoherentInstances #-} module PolyTest where import Data.Monoid class Monoid m = Monoidable a m where toMonoid :: a - m squish :: Monoidable a m = m - a - m squish m a = (m `mappend` (toMonoid a)) class Monoid m = PolyVariadic m r where polyToMonoid :: m - r instance (Monoid m', m' ~ m) = PolyVariadic m m' where polyToMonoid acc = acc instance (Monoidable a m, PolyVariadic m r) = PolyVariadic m (a-r) where polyToMonoid acc = \a - polyToMonoid (squish acc a) Here are three examples. The resulting notation is short enough now that I am no longer tempted to use CPP. All you need to do is to specify the type for mempty. And even this can be skipped if you want to put in the specific mempty value (although I think that the type annotation is often better if slightly longer as it documents clearly what monoid the result is being mapped into). -- [String] example instance Show a = Monoidable a [String] where toMonoid a = [show a] testStringList = putStrLn $ show $ polyToMonoid (mempty :: [String]) True () (Just (5::Int)) -- String example instance Show a = Monoidable a String where toMonoid a = show a testString = putStrLn $ polyToMonoid (mempty :: String) True () (Just (5::Int)) -- product example instance Monoid Double where mappend = (*) mempty = (1.0) :: Double instance Monoidable Int Double where toMonoid = fromIntegral instance Monoidable Double Double where toMonoid = id testProduct = putStrLn $ show $ polyToMonoid (mempty :: Double) (5 :: Int) (2.3 :: Double) (3 :: Int) (8 :: Int) main = do testStringList testString testProduct $ runhaskell PolyTest.hs [True,(),Just 5] True()Just 5 276.0 Kevin On Oct 11, 2:39 am, o...@okmij.org wrote: Sorry, I'm still catching up. I'm replying to first few messages. instance Show a = Monoidable a [String] where toMonoid a = [show a] main = putStrLn $ unwrap $ polyToMonoid [] True () (Just (5::Int)) fails to compile. The error message points to the first problem: No instances for (Monoidable Bool [a], Monoidable () [a], ... The presence of the type variable 'a' means that the type checker doesn't know list of what elements you want (in other words, the context is not specific enough to instantiate the type variable a). Thus, we need to explicitly tell that we wish a list of strings: test3 = putStrLn $ unwrap $polyToMonoid ([]::[String]) True () (Just (5::Int)) Now we get a different error, which points to the real problem this time: the expression `unwrap ' appears as an argument to putStrLn. That means that we are required to produce a String as a monoid. Yet we specified ([]::[String]) as mempty, which is unsuitable as mempty for the String monoid. If we desire the [String] monoid as the result, we need to change the context. For example, test3 = mapM_ putStrLn $ unwrap $ polyToMonoid ([]::[String]) True () (Just (5::Int)) Another example that also fails to compile (but I cannot see why): main = putStrLn $ show $ unwrap $ polyToMonoid (0::Int) (1::Int) (2::Int) (3::Int) No instance for (PolyVariadic Int (WMonoid m)) arising from a use of `polyToMonoid' The error message is informative, mentioning the type variable, m. Whenever that happens, we know that we put a bounded polymorphic expression in the context that is not specific enough. We need some type annotations. In our case, the function 'show' can show values of many types. The type checker does not know that we wish an Int monoid specifically. So, we have to specialize the show
[Haskell-cafe] Re: Polyvariadic functions operating with a monoid
Hi Brandon, True, when I replace [] with [], I get a different error message: No instance for (PolyVariadic [[Char]] (WMonoid String)) which now looks a bit like the Int example. In both cases, GHC appears to be unable to derive the appropriate instance of PolyVariadic. Why this is so, but worked for Oleg's specific example. is still not clear to me. Kevin On Oct 9, 11:51 pm, Brandon S Allbery KF8NH allb...@ece.cmu.edu wrote: -BEGIN PGP SIGNED MESSAGE- Hash: SHA1 On 10/9/10 10:25 , Kevin Jardine wrote: instance Show a = Monoidable a [String] where toMonoid a = [show a] main = putStrLn $ unwrap $ polyToMonoid [] True () (Just (5::Int)) fails to compile. Why would that be? My understanding is that all lists are automatically monoids. I *think* the problem here is that Oleg specifically pointed out that the first parameter to polyToMonoid must specify the type of the monoid. [] tells you it's a list, therefore a monoid, but it doesn't say enough to allow the [String] instance to be chosen. (No, the fact that you only declared an instance for [String] isn't really enough.) - -- brandon s. allbery [linux,solaris,freebsd,perl] allb...@kf8nh.com system administrator [openafs,heimdal,too many hats] allb...@ece.cmu.edu electrical and computer engineering, carnegie mellon university KF8NH -BEGIN PGP SIGNATURE- Version: GnuPG v2.0.10 (Darwin) Comment: Using GnuPG with Mozilla -http://enigmail.mozdev.org/ iEYEARECAAYFAkyw49wACgkQIn7hlCsL25VZygCfVETk+3AZ3gKoBy4pZ7j8g4Km WXgAnjrbO9rEl2HnQtGQ31EyRuhWzI4r =YMDw -END PGP SIGNATURE- ___ Haskell-Cafe mailing list haskell-c...@haskell.orghttp://www.haskell.org/mailman/listinfo/haskell-cafe ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] Re: Polyvariadic functions operating with a monoid
And in fact in both cases, it appears that GHC is trying to derive the *wrong* instances of PolyVariadic. It should be deriving: PolyVariadic Int (WMonoid Int) not PolyVariadic Int (WMonoid m) and PolyVariadic [String] (WMonoid [String]) not PolyVariadic [String] (WMonoid String) specifically, GHC is attempting to derive PolyVariadic with the wrong version of WMonoid in each case. I'm using GHC 6.12.3 Perhaps the new GHC 7 type system would work better? Kevin On Oct 10, 8:26 am, Kevin Jardine kevinjard...@gmail.com wrote: Hi Brandon, True, when I replace [] with [], I get a different error message: No instance for (PolyVariadic [[Char]] (WMonoid String)) which now looks a bit like the Int example. In both cases, GHC appears to be unable to derive the appropriate instance of PolyVariadic. Why this is so, but worked for Oleg's specific example. is still not clear to me. Kevin On Oct 9, 11:51 pm, Brandon S Allbery KF8NH allb...@ece.cmu.edu wrote: -BEGIN PGP SIGNED MESSAGE- Hash: SHA1 On 10/9/10 10:25 , Kevin Jardine wrote: instance Show a = Monoidable a [String] where toMonoid a = [show a] main = putStrLn $ unwrap $ polyToMonoid [] True () (Just (5::Int)) fails to compile. Why would that be? My understanding is that all lists are automatically monoids. I *think* the problem here is that Oleg specifically pointed out that the first parameter to polyToMonoid must specify the type of the monoid. [] tells you it's a list, therefore a monoid, but it doesn't say enough to allow the [String] instance to be chosen. (No, the fact that you only declared an instance for [String] isn't really enough.) - -- brandon s. allbery [linux,solaris,freebsd,perl] allb...@kf8nh.com system administrator [openafs,heimdal,too many hats] allb...@ece.cmu.edu electrical and computer engineering, carnegie mellon university KF8NH -BEGIN PGP SIGNATURE- Version: GnuPG v2.0.10 (Darwin) Comment: Using GnuPG with Mozilla -http://enigmail.mozdev.org/ iEYEARECAAYFAkyw49wACgkQIn7hlCsL25VZygCfVETk+3AZ3gKoBy4pZ7j8g4Km WXgAnjrbO9rEl2HnQtGQ31EyRuhWzI4r =YMDw -END PGP SIGNATURE- ___ Haskell-Cafe mailing list haskell-c...@haskell.orghttp://www.haskell.org/mailman/listinfo/haskell-cafe ___ Haskell-Cafe mailing list haskell-c...@haskell.orghttp://www.haskell.org/mailman/listinfo/haskell-cafe ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] Re: Polyvariadic functions operating with a monoid
OK, upon further investigation, the problem is that GHC cannot in general infer the return type of polyToMonoid despite the hint it is given (the type signature of the first parameter). If I write: main = putStrLn $ show $ unwrap $ ((polyToMonoid [] True (Just (5::Int))) :: WMonoid [String]) or main = putStrLn $ show $ unwrap $ ((polyToMonoid (0::Int) (1::Int) (2::Int) (3::Int)) :: WMonoid Int) the code compiles and returns the expected result. Kevin On Oct 10, 8:58 am, Kevin Jardine kevinjard...@gmail.com wrote: And in fact in both cases, it appears that GHC is trying to derive the *wrong* instances of PolyVariadic. It should be deriving: PolyVariadic Int (WMonoid Int) not PolyVariadic Int (WMonoid m) and PolyVariadic [String] (WMonoid [String]) not PolyVariadic [String] (WMonoid String) specifically, GHC is attempting to derive PolyVariadic with the wrong version of WMonoid in each case. I'm using GHC 6.12.3 Perhaps the new GHC 7 type system would work better? Kevin On Oct 10, 8:26 am, Kevin Jardine kevinjard...@gmail.com wrote: Hi Brandon, True, when I replace [] with [], I get a different error message: No instance for (PolyVariadic [[Char]] (WMonoid String)) which now looks a bit like the Int example. In both cases, GHC appears to be unable to derive the appropriate instance of PolyVariadic. Why this is so, but worked for Oleg's specific example. is still not clear to me. Kevin On Oct 9, 11:51 pm, Brandon S Allbery KF8NH allb...@ece.cmu.edu wrote: -BEGIN PGP SIGNED MESSAGE- Hash: SHA1 On 10/9/10 10:25 , Kevin Jardine wrote: instance Show a = Monoidable a [String] where toMonoid a = [show a] main = putStrLn $ unwrap $ polyToMonoid [] True () (Just (5::Int)) fails to compile. Why would that be? My understanding is that all lists are automatically monoids. I *think* the problem here is that Oleg specifically pointed out that the first parameter to polyToMonoid must specify the type of the monoid. [] tells you it's a list, therefore a monoid, but it doesn't say enough to allow the [String] instance to be chosen. (No, the fact that you only declared an instance for [String] isn't really enough.) - -- brandon s. allbery [linux,solaris,freebsd,perl] allb...@kf8nh.com system administrator [openafs,heimdal,too many hats] allb...@ece.cmu.edu electrical and computer engineering, carnegie mellon university KF8NH -BEGIN PGP SIGNATURE- Version: GnuPG v2.0.10 (Darwin) Comment: Using GnuPG with Mozilla -http://enigmail.mozdev.org/ iEYEARECAAYFAkyw49wACgkQIn7hlCsL25VZygCfVETk+3AZ3gKoBy4pZ7j8g4Km WXgAnjrbO9rEl2HnQtGQ31EyRuhWzI4r =YMDw -END PGP SIGNATURE- ___ Haskell-Cafe mailing list haskell-c...@haskell.orghttp://www.haskell.org/mailman/listinfo/haskell-cafe ___ Haskell-Cafe mailing list haskell-c...@haskell.orghttp://www.haskell.org/mailman/listinfo/haskell-cafe ___ Haskell-Cafe mailing list haskell-c...@haskell.orghttp://www.haskell.org/mailman/listinfo/haskell-cafe ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] Re: Polyvariadic functions operating with a monoid
For anyone who's interested, the code I have now is: {-# LANGUAGE TypeSynonymInstances, FlexibleInstances, MultiParamTypeClasses #-} module PolyTest where import Data.Monoid class Monoid m = Monoidable a m where toMonoid :: a - m squish :: Monoidable a m = m - a - m squish m a = (m `mappend` (toMonoid a)) class Monoid m = PolyVariadic m r where polyToMonoid :: m - r instance Monoid m = PolyVariadic m m where polyToMonoid acc = acc instance (Monoidable a m, PolyVariadic m r) = PolyVariadic m (a-r) where polyToMonoid acc = \a - polyToMonoid (squish acc a) and three example uses are: -- [String] example instance Show a = Monoidable a [String] where toMonoid a = [show a] testStringList = putStrLn $ show $ ((polyToMonoid [] True () (Just (5::Int))) :: [String]) -- String example instance Show a = Monoidable a String where toMonoid a = show a testString = putStrLn $ ((polyToMonoid True () (Just (5::Int))) :: String) -- sum example instance Monoid Int where mappend = (+) mempty = 0 instance Monoidable Int Int where toMonoid = id testSum = putStrLn $ show $ ((polyToMonoid (0::Int) (1::Int) (2::Int) (3::Int)) :: Int) main = do testStringList testString testSum $ runhaskell PolyTest.hs [,True,(),Just 5] True()Just 5 6 This removes the unwrap and I don't mind the need for the outer type cast. I do wonder if there is a need for the first (dummy) parameter to communicate the type as well as this seems redundant given the outer type cast but I can't find a way to remove it. It appears that GHC needs to be told the type both coming and going so to speak for this to work consistently. Any suggestions for improvement welcome! Kevin On Oct 10, 11:12 am, Kevin Jardine kevinjard...@gmail.com wrote: OK, upon further investigation, the problem is that GHC cannot in general infer the return type of polyToMonoid despite the hint it is given (the type signature of the first parameter). If I write: main = putStrLn $ show $ unwrap $ ((polyToMonoid [] True (Just (5::Int))) :: WMonoid [String]) or main = putStrLn $ show $ unwrap $ ((polyToMonoid (0::Int) (1::Int) (2::Int) (3::Int)) :: WMonoid Int) the code compiles and returns the expected result. Kevin On Oct 10, 8:58 am, Kevin Jardine kevinjard...@gmail.com wrote: And in fact in both cases, it appears that GHC is trying to derive the *wrong* instances of PolyVariadic. It should be deriving: PolyVariadic Int (WMonoid Int) not PolyVariadic Int (WMonoid m) and PolyVariadic [String] (WMonoid [String]) not PolyVariadic [String] (WMonoid String) specifically, GHC is attempting to derive PolyVariadic with the wrong version of WMonoid in each case. I'm using GHC 6.12.3 Perhaps the new GHC 7 type system would work better? Kevin On Oct 10, 8:26 am, Kevin Jardine kevinjard...@gmail.com wrote: Hi Brandon, True, when I replace [] with [], I get a different error message: No instance for (PolyVariadic [[Char]] (WMonoid String)) which now looks a bit like the Int example. In both cases, GHC appears to be unable to derive the appropriate instance of PolyVariadic. Why this is so, but worked for Oleg's specific example. is still not clear to me. Kevin On Oct 9, 11:51 pm, Brandon S Allbery KF8NH allb...@ece.cmu.edu wrote: -BEGIN PGP SIGNED MESSAGE- Hash: SHA1 On 10/9/10 10:25 , Kevin Jardine wrote: instance Show a = Monoidable a [String] where toMonoid a = [show a] main = putStrLn $ unwrap $ polyToMonoid [] True () (Just (5::Int)) fails to compile. Why would that be? My understanding is that all lists are automatically monoids. I *think* the problem here is that Oleg specifically pointed out that the first parameter to polyToMonoid must specify the type of the monoid. [] tells you it's a list, therefore a monoid, but it doesn't say enough to allow the [String] instance to be chosen. (No, the fact that you only declared an instance for [String] isn't really enough.) - -- brandon s. allbery [linux,solaris,freebsd,perl] allb...@kf8nh.com system administrator [openafs,heimdal,too many hats] allb...@ece.cmu.edu electrical and computer engineering, carnegie mellon university KF8NH -BEGIN PGP SIGNATURE- Version: GnuPG v2.0.10 (Darwin) Comment: Using GnuPG with Mozilla -http://enigmail.mozdev.org/ iEYEARECAAYFAkyw49wACgkQIn7hlCsL25VZygCfVETk+3AZ3gKoBy4pZ7j8g4Km WXgAnjrbO9rEl2HnQtGQ31EyRuhWzI4r =YMDw -END PGP SIGNATURE- ___ Haskell-Cafe mailing list haskell-c...@haskell.orghttp://www.haskell.org/mailman/listinfo/haskell-cafe ___ Haskell-Cafe mailing list haskell-c...@haskell.orghttp://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] Re: Polyvariadic functions operating with a monoid
It is interesting to see that the dummy parameters can actually be replaced by: mempty :: [String] mempty :: String mempty: Int in my three examples and the code still compiles and gives the expected results. This suggests that a further simplification might be possible (ideally in straight Haskell, but if not then with CPP or Template Haskell). Kevin On Oct 10, 1:28 pm, Kevin Jardine kevinjard...@gmail.com wrote: For anyone who's interested, the code I have now is: {-# LANGUAGE TypeSynonymInstances, FlexibleInstances, MultiParamTypeClasses #-} module PolyTest where import Data.Monoid class Monoid m = Monoidable a m where toMonoid :: a - m squish :: Monoidable a m = m - a - m squish m a = (m `mappend` (toMonoid a)) class Monoid m = PolyVariadic m r where polyToMonoid :: m - r instance Monoid m = PolyVariadic m m where polyToMonoid acc = acc instance (Monoidable a m, PolyVariadic m r) = PolyVariadic m (a-r) where polyToMonoid acc = \a - polyToMonoid (squish acc a) and three example uses are: -- [String] example instance Show a = Monoidable a [String] where toMonoid a = [show a] testStringList = putStrLn $ show $ ((polyToMonoid [] True () (Just (5::Int))) :: [String]) -- String example instance Show a = Monoidable a String where toMonoid a = show a testString = putStrLn $ ((polyToMonoid True () (Just (5::Int))) :: String) -- sum example instance Monoid Int where mappend = (+) mempty = 0 instance Monoidable Int Int where toMonoid = id testSum = putStrLn $ show $ ((polyToMonoid (0::Int) (1::Int) (2::Int) (3::Int)) :: Int) main = do testStringList testString testSum $ runhaskell PolyTest.hs [,True,(),Just 5] True()Just 5 6 This removes the unwrap and I don't mind the need for the outer type cast. I do wonder if there is a need for the first (dummy) parameter to communicate the type as well as this seems redundant given the outer type cast but I can't find a way to remove it. It appears that GHC needs to be told the type both coming and going so to speak for this to work consistently. Any suggestions for improvement welcome! Kevin On Oct 10, 11:12 am, Kevin Jardine kevinjard...@gmail.com wrote: OK, upon further investigation, the problem is that GHC cannot in general infer the return type of polyToMonoid despite the hint it is given (the type signature of the first parameter). If I write: main = putStrLn $ show $ unwrap $ ((polyToMonoid [] True (Just (5::Int))) :: WMonoid [String]) or main = putStrLn $ show $ unwrap $ ((polyToMonoid (0::Int) (1::Int) (2::Int) (3::Int)) :: WMonoid Int) the code compiles and returns the expected result. Kevin On Oct 10, 8:58 am, Kevin Jardine kevinjard...@gmail.com wrote: And in fact in both cases, it appears that GHC is trying to derive the *wrong* instances of PolyVariadic. It should be deriving: PolyVariadic Int (WMonoid Int) not PolyVariadic Int (WMonoid m) and PolyVariadic [String] (WMonoid [String]) not PolyVariadic [String] (WMonoid String) specifically, GHC is attempting to derive PolyVariadic with the wrong version of WMonoid in each case. I'm using GHC 6.12.3 Perhaps the new GHC 7 type system would work better? Kevin On Oct 10, 8:26 am, Kevin Jardine kevinjard...@gmail.com wrote: Hi Brandon, True, when I replace [] with [], I get a different error message: No instance for (PolyVariadic [[Char]] (WMonoid String)) which now looks a bit like the Int example. In both cases, GHC appears to be unable to derive the appropriate instance of PolyVariadic. Why this is so, but worked for Oleg's specific example. is still not clear to me. Kevin On Oct 9, 11:51 pm, Brandon S Allbery KF8NH allb...@ece.cmu.edu wrote: -BEGIN PGP SIGNED MESSAGE- Hash: SHA1 On 10/9/10 10:25 , Kevin Jardine wrote: instance Show a = Monoidable a [String] where toMonoid a = [show a] main = putStrLn $ unwrap $ polyToMonoid [] True () (Just (5::Int)) fails to compile. Why would that be? My understanding is that all lists are automatically monoids. I *think* the problem here is that Oleg specifically pointed out that the first parameter to polyToMonoid must specify the type of the monoid. [] tells you it's a list, therefore a monoid, but it doesn't say enough to allow the [String] instance to be chosen. (No, the fact that you only declared an instance for [String] isn't really enough.) - -- brandon s. allbery [linux,solaris,freebsd,perl] allb...@kf8nh.com system administrator [openafs,heimdal,too many hats] allb...@ece.cmu.edu electrical and computer engineering, carnegie mellon university KF8NH -BEGIN PGP SIGNATURE- Version: GnuPG v2.0.10 (Darwin
[Haskell-cafe] Re: Polyvariadic functions operating with a monoid
For example, the notation can be reduced to: poly([String],True () (Just (5::Int))) using: #define poly(TYPE,VALUES) ((polyToMonoid (mempty :: TYPE) VALUES) :: TYPE) which I think is as concise as it can get. Kevin On Oct 10, 1:47 pm, Kevin Jardine kevinjard...@gmail.com wrote: It is interesting to see that the dummy parameters can actually be replaced by: mempty :: [String] mempty :: String mempty: Int in my three examples and the code still compiles and gives the expected results. This suggests that a further simplification might be possible (ideally in straight Haskell, but if not then with CPP or Template Haskell). Kevin On Oct 10, 1:28 pm, Kevin Jardine kevinjard...@gmail.com wrote: For anyone who's interested, the code I have now is: {-# LANGUAGE TypeSynonymInstances, FlexibleInstances, MultiParamTypeClasses #-} module PolyTest where import Data.Monoid class Monoid m = Monoidable a m where toMonoid :: a - m squish :: Monoidable a m = m - a - m squish m a = (m `mappend` (toMonoid a)) class Monoid m = PolyVariadic m r where polyToMonoid :: m - r instance Monoid m = PolyVariadic m m where polyToMonoid acc = acc instance (Monoidable a m, PolyVariadic m r) = PolyVariadic m (a-r) where polyToMonoid acc = \a - polyToMonoid (squish acc a) and three example uses are: -- [String] example instance Show a = Monoidable a [String] where toMonoid a = [show a] testStringList = putStrLn $ show $ ((polyToMonoid [] True () (Just (5::Int))) :: [String]) -- String example instance Show a = Monoidable a String where toMonoid a = show a testString = putStrLn $ ((polyToMonoid True () (Just (5::Int))) :: String) -- sum example instance Monoid Int where mappend = (+) mempty = 0 instance Monoidable Int Int where toMonoid = id testSum = putStrLn $ show $ ((polyToMonoid (0::Int) (1::Int) (2::Int) (3::Int)) :: Int) main = do testStringList testString testSum $ runhaskell PolyTest.hs [,True,(),Just 5] True()Just 5 6 This removes the unwrap and I don't mind the need for the outer type cast. I do wonder if there is a need for the first (dummy) parameter to communicate the type as well as this seems redundant given the outer type cast but I can't find a way to remove it. It appears that GHC needs to be told the type both coming and going so to speak for this to work consistently. Any suggestions for improvement welcome! Kevin On Oct 10, 11:12 am, Kevin Jardine kevinjard...@gmail.com wrote: OK, upon further investigation, the problem is that GHC cannot in general infer the return type of polyToMonoid despite the hint it is given (the type signature of the first parameter). If I write: main = putStrLn $ show $ unwrap $ ((polyToMonoid [] True (Just (5::Int))) :: WMonoid [String]) or main = putStrLn $ show $ unwrap $ ((polyToMonoid (0::Int) (1::Int) (2::Int) (3::Int)) :: WMonoid Int) the code compiles and returns the expected result. Kevin On Oct 10, 8:58 am, Kevin Jardine kevinjard...@gmail.com wrote: And in fact in both cases, it appears that GHC is trying to derive the *wrong* instances of PolyVariadic. It should be deriving: PolyVariadic Int (WMonoid Int) not PolyVariadic Int (WMonoid m) and PolyVariadic [String] (WMonoid [String]) not PolyVariadic [String] (WMonoid String) specifically, GHC is attempting to derive PolyVariadic with the wrong version of WMonoid in each case. I'm using GHC 6.12.3 Perhaps the new GHC 7 type system would work better? Kevin On Oct 10, 8:26 am, Kevin Jardine kevinjard...@gmail.com wrote: Hi Brandon, True, when I replace [] with [], I get a different error message: No instance for (PolyVariadic [[Char]] (WMonoid String)) which now looks a bit like the Int example. In both cases, GHC appears to be unable to derive the appropriate instance of PolyVariadic. Why this is so, but worked for Oleg's specific example. is still not clear to me. Kevin On Oct 9, 11:51 pm, Brandon S Allbery KF8NH allb...@ece.cmu.edu wrote: -BEGIN PGP SIGNED MESSAGE- Hash: SHA1 On 10/9/10 10:25 , Kevin Jardine wrote: instance Show a = Monoidable a [String] where toMonoid a = [show a] main = putStrLn $ unwrap $ polyToMonoid [] True () (Just (5::Int)) fails to compile. Why would that be? My understanding is that all lists are automatically monoids. I *think* the problem here is that Oleg specifically pointed out that the first parameter to polyToMonoid must specify the type of the monoid. [] tells you it's a list, therefore a monoid, but it doesn't say enough to allow the [String] instance to be chosen. (No, the fact that you only
[Haskell-cafe] Re: Polyvariadic functions operating with a monoid
One final example to end with: -- mixed type product example instance Monoid Double where mappend = (*) mempty = (1.0) :: Double instance Monoidable Int Double where toMonoid = fromIntegral instance Monoidable Double Double where toMonoid = id #define productOf(VALUES) poly(Double,VALUES) testProduct = putStrLn $ show $ productOf ( (5 :: Int) (2.3 :: Double) (3 :: Int) (8 :: Int) ) If anyone has a better alternative to the CPP macros, I'd be interested to hear it. I think that this is interesting enough to create a PolyvariadicFromMonoid library as it seems to be a fast way to create a large number of polyvariadic functions - basicially, just set up your Monoid definition and your toMonoid conversion functions and then you get the appropriate polvariadic function for free. Thanks for the input from everyone and Oleg especially for creating working code! Kevin On Oct 10, 2:51 pm, Kevin Jardine kevinjard...@gmail.com wrote: For example, the notation can be reduced to: poly([String],True () (Just (5::Int))) using: #define poly(TYPE,VALUES) ((polyToMonoid (mempty :: TYPE) VALUES) :: TYPE) which I think is as concise as it can get. Kevin On Oct 10, 1:47 pm, Kevin Jardine kevinjard...@gmail.com wrote: It is interesting to see that the dummy parameters can actually be replaced by: mempty :: [String] mempty :: String mempty: Int in my three examples and the code still compiles and gives the expected results. This suggests that a further simplification might be possible (ideally in straight Haskell, but if not then with CPP or Template Haskell). Kevin On Oct 10, 1:28 pm, Kevin Jardine kevinjard...@gmail.com wrote: For anyone who's interested, the code I have now is: {-# LANGUAGE TypeSynonymInstances, FlexibleInstances, MultiParamTypeClasses #-} module PolyTest where import Data.Monoid class Monoid m = Monoidable a m where toMonoid :: a - m squish :: Monoidable a m = m - a - m squish m a = (m `mappend` (toMonoid a)) class Monoid m = PolyVariadic m r where polyToMonoid :: m - r instance Monoid m = PolyVariadic m m where polyToMonoid acc = acc instance (Monoidable a m, PolyVariadic m r) = PolyVariadic m (a-r) where polyToMonoid acc = \a - polyToMonoid (squish acc a) and three example uses are: -- [String] example instance Show a = Monoidable a [String] where toMonoid a = [show a] testStringList = putStrLn $ show $ ((polyToMonoid [] True () (Just (5::Int))) :: [String]) -- String example instance Show a = Monoidable a String where toMonoid a = show a testString = putStrLn $ ((polyToMonoid True () (Just (5::Int))) :: String) -- sum example instance Monoid Int where mappend = (+) mempty = 0 instance Monoidable Int Int where toMonoid = id testSum = putStrLn $ show $ ((polyToMonoid (0::Int) (1::Int) (2::Int) (3::Int)) :: Int) main = do testStringList testString testSum $ runhaskell PolyTest.hs [,True,(),Just 5] True()Just 5 6 This removes the unwrap and I don't mind the need for the outer type cast. I do wonder if there is a need for the first (dummy) parameter to communicate the type as well as this seems redundant given the outer type cast but I can't find a way to remove it. It appears that GHC needs to be told the type both coming and going so to speak for this to work consistently. Any suggestions for improvement welcome! Kevin On Oct 10, 11:12 am, Kevin Jardine kevinjard...@gmail.com wrote: OK, upon further investigation, the problem is that GHC cannot in general infer the return type of polyToMonoid despite the hint it is given (the type signature of the first parameter). If I write: main = putStrLn $ show $ unwrap $ ((polyToMonoid [] True (Just (5::Int))) :: WMonoid [String]) or main = putStrLn $ show $ unwrap $ ((polyToMonoid (0::Int) (1::Int) (2::Int) (3::Int)) :: WMonoid Int) the code compiles and returns the expected result. Kevin On Oct 10, 8:58 am, Kevin Jardine kevinjard...@gmail.com wrote: And in fact in both cases, it appears that GHC is trying to derive the *wrong* instances of PolyVariadic. It should be deriving: PolyVariadic Int (WMonoid Int) not PolyVariadic Int (WMonoid m) and PolyVariadic [String] (WMonoid [String]) not PolyVariadic [String] (WMonoid String) specifically, GHC is attempting to derive PolyVariadic with the wrong version of WMonoid in each case. I'm using GHC 6.12.3 Perhaps the new GHC 7 type system would work better? Kevin On Oct 10, 8:26 am, Kevin Jardine kevinjard...@gmail.com wrote: Hi Brandon, True, when I replace [] with [], I get a different error message: No instance for (PolyVariadic [[Char]] (WMonoid String
[Haskell-cafe] Re: Polyvariadic functions operating with a monoid
Hi Oleg, Thank you for this wonderful detailed solution! I was attempting to turn this into a small library and wanted to avoid exporting unwrap. I defined: polyToMonoid' = unwrap . polyToMonoid and then GHC told me: No instance for (PolyVariadic a (WMonoid m)) arising from a use of `polyToMonoid' at Data\PolyToMonoid.hs:27:24-36 Possible fix: add an instance declaration for (PolyVariadic a (WMonoid m)) Is there a type signature I can assign to polyToMonoid' to get this to work? Or will it always be necessary to export unwrap as well? Kevin On Oct 9, 5:04 am, o...@okmij.org wrote: Kevin Jardine wrote: instead of passing around lists of values with these related types, I created a polyvariadic function polyToString... I finally figured out how to do this, but it was a bit harder to figure this out than I expected, and I was wondering if it might be possible to create a small utility library to help other developers do this. It seems to me that in the general case, we would be dealing with a Monoid rather than a list of strings. We could have a toMonoid function and then return polyToMonoid value1 value2 ... valueN = (toMonoid value1) `mappend` (toMonoid value2) 'mappend' ... (toMonoid valueN) So I tried writing the following code but GHC said it had undecidable instances. Generally speaking, we should not be afraid of undecidable instances: it is a sufficient criterion for terminating type checking but it is not a necessary one. A longer argument can be found at http://okmij.org/ftp/Haskell/types.html#undecidable-inst-defense However, the posted code has deeper problems, I'm afraid. First, let us look at the case of Strings: class PolyVariadic p where polyToMonoid' :: String - p instance PolyVariadic String where polyToMonoid' acc = acc instance (Show a, PolyVariadic r) = PolyVariadic (a-r) where polyToMonoid' acc = \a - polyToMonoid' (acc ++ show a) polyToMonoid :: PolyVariadic p = p polyToMonoid = polyToMonoid' mempty test1 = putStrLn $ polyToMonoid True () (Just (5::Int)) *M test1 True()Just 5 Modulo the TypeSynonymInstances extension, it is Haskell98. If we now generalize it to arbitrary monoids rather than a mere String, we face several problems. First of all, if we re-write the first instance as instance Monoid r = PolyVariadic r where polyToMonoid' acc = acc we make it overlap with the second instance: the type variable 'r' may be instantiated to the arrow type a-r'. Now we need a more problematic overlapping instances extension. The problem is deeper however: an arrow type could possibly be an instance of Monoid (for example, functions of the type Int-Int form a monoid with mempty=id, mappend=(.)). If polyToMonoid appears in the context requiring a function type, how could type checker choose the instance of Polyvariadic? The second problem with the posted code class Monoidable a where toMonoid :: Monoid r = a - r is that toMonoid has too `strong' a signature. Suppose we have an instance instance Monoidable String where toMonoid = \str - ??? It means that no matter which monoid the programmer may give to us, we promise to inject a string into it. We have no idea about the details of the monoid. It means that the only thing we could do (short of divergence) is to return mempty. That is not too useful. We have little choice but to parametrise Monoidable as well as Polyvariadic with the type of the monoid. To avoid overlapping and disambiguate the contexts, we use the newtype trick. Here is the complete code. It turns out, no undecidable instances are needed. {-# LANGUAGE TypeSynonymInstances #-} {-# LANGUAGE MultiParamTypeClasses, FlexibleInstances #-} module M where import Data.Monoid newtype WMonoid m = WMonoid{unwrap :: m} class Monoid m = Monoidable a m where toMonoid :: a - m class Monoid m = PolyVariadic m p where polyToMonoid :: m - p instance Monoid m = PolyVariadic m (WMonoid m) where polyToMonoid acc = WMonoid acc instance (Monoidable a m, PolyVariadic m r) = PolyVariadic m (a-r) where polyToMonoid acc = \a - polyToMonoid (acc `mappend` toMonoid a) instance Show a = Monoidable a String where toMonoid = show test2 = putStrLn $ unwrap $ polyToMonoid True () (Just (5::Int)) The remaining problem is how to tell polyToMonoid which monoid we want. It seems simpler just to pass the appropriately specialized mempty method as the first argument, as shown in test2. Granted, a more elegant solution would be a parametrized module (functor) like those in Agda or ML: module type PolyM = functor(M:: sig type m val mempty :: m val mappend :: m - m - m end) = struct class Monoidable a where toMonoid :: a - m class PolyVariadic p where polyToMonoid :: m - p .etc end The shown solution is essentially the encoding of the above functor
[Haskell-cafe] Re: Polyvariadic functions operating with a monoid
Hi Bartek, Yes, it compiles, but when I try to use polyToMonoid', it turns out that this function is no longer polyvariadic, unlike the original polyToMonoid . This may be what Luke meant when he wrote you lose composability. Even with the extra unwrap function I think that this is pretty cool, but I would ideally like to hide the unwrap. Kevin On Oct 9, 1:50 pm, Bartek Ćwikłowski paczesi...@gmail.com wrote: Hello Kevin, 2010/10/9 Kevin Jardine kevinjard...@gmail.com: I was attempting to turn this into a small library and wanted to avoid exporting unwrap. I defined: polyToMonoid' = unwrap . polyToMonoid If you disable MonomorphismRestriction this definition typechecks just fine. Alternatively, you can ask ghci about the type of unwrap . polyToMonoid and paste that into the type sig. regards, Bartek Ćwikłowski ___ Haskell-Cafe mailing list haskell-c...@haskell.orghttp://www.haskell.org/mailman/listinfo/haskell-cafe ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] Re: Polyvariadic functions operating with a monoid
Oleg, Another puzzle is that: instance Show a = Monoidable a String where toMonoid a = show a main = putStrLn $ unwrap $ polyToMonoid True () (Just (5::Int)) works just fine, but instance Show a = Monoidable a [String] where toMonoid a = [show a] main = putStrLn $ unwrap $ polyToMonoid [] True () (Just (5::Int)) fails to compile. Why would that be? My understanding is that all lists are automatically monoids. Kevin On Oct 9, 2:28 pm, Kevin Jardine kevinjard...@gmail.com wrote: Hi Bartek, Yes, it compiles, but when I try to use polyToMonoid', it turns out that this function is no longer polyvariadic, unlike the original polyToMonoid . This may be what Luke meant when he wrote you lose composability. Even with the extra unwrap function I think that this is pretty cool, but I would ideally like to hide the unwrap. Kevin On Oct 9, 1:50 pm, Bartek Æwik³owski paczesi...@gmail.com wrote: Hello Kevin, 2010/10/9 Kevin Jardine kevinjard...@gmail.com: I was attempting to turn this into a small library and wanted to avoid exporting unwrap. I defined: polyToMonoid' = unwrap . polyToMonoid If you disable MonomorphismRestriction this definition typechecks just fine. Alternatively, you can ask ghci about the type of unwrap . polyToMonoid and paste that into the type sig. regards, Bartek Æwik³owski ___ Haskell-Cafe mailing list haskell-c...@haskell.orghttp://www.haskell.org/mailman/listinfo/haskell-cafe ___ Haskell-Cafe mailing list haskell-c...@haskell.orghttp://www.haskell.org/mailman/listinfo/haskell-cafe ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] Re: Polyvariadic functions operating with a monoid
Another example that also fails to compile (but I cannot see why): import Data.PolyToMonoid import Data.Monoid instance Monoid Int where mappend = (+) mempty = 0 instance Monoidable Int Int where toMonoid = id main = putStrLn $ show $ unwrap $ polyToMonoid (0::Int) (1::Int) (2::Int) (3::Int) In this case, I was expecting a sumOf function. This gives me: No instance for (PolyVariadic Int (WMonoid m)) arising from a use of `polyToMonoid' Any further suggestions? On Oct 9, 4:25 pm, Kevin Jardine kevinjard...@gmail.com wrote: Oleg, Another puzzle is that: instance Show a = Monoidable a String where toMonoid a = show a main = putStrLn $ unwrap $ polyToMonoid True () (Just (5::Int)) works just fine, but instance Show a = Monoidable a [String] where toMonoid a = [show a] main = putStrLn $ unwrap $ polyToMonoid [] True () (Just (5::Int)) fails to compile. Why would that be? My understanding is that all lists are automatically monoids. Kevin On Oct 9, 2:28 pm, Kevin Jardine kevinjard...@gmail.com wrote: Hi Bartek, Yes, it compiles, but when I try to use polyToMonoid', it turns out that this function is no longer polyvariadic, unlike the original polyToMonoid . This may be what Luke meant when he wrote you lose composability. Even with the extra unwrap function I think that this is pretty cool, but I would ideally like to hide the unwrap. Kevin On Oct 9, 1:50 pm, Bartek Æwik³owski paczesi...@gmail.com wrote: Hello Kevin, 2010/10/9 Kevin Jardine kevinjard...@gmail.com: I was attempting to turn this into a small library and wanted to avoid exporting unwrap. I defined: polyToMonoid' = unwrap . polyToMonoid If you disable MonomorphismRestriction this definition typechecks just fine. Alternatively, you can ask ghci about the type of unwrap . polyToMonoid and paste that into the type sig. regards, Bartek Æwik³owski ___ Haskell-Cafe mailing list haskell-c...@haskell.orghttp://www.haskell.org/mailman/listinfo/haskell-cafe ___ Haskell-Cafe mailing list haskell-c...@haskell.orghttp://www.haskell.org/mailman/listinfo/haskell-cafe ___ Haskell-Cafe mailing list haskell-c...@haskell.orghttp://www.haskell.org/mailman/listinfo/haskell-cafe ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] Polyvariadic functions operating with a monoid
I had a situation where I had some related types that all had toString functions. Of course in Haskell, lists all have to be composed of values of exactly the same type, so instead of passing around lists of values with these related types, I created a polyvariadic function polyToString so that I could write: (polyToString value1 value2 value3 ... valueN) which would then become a list of strings: [toString value1, toString value2, ... , toString valueN] I finally figured out how to do this, but it was a bit harder to figure this out than I expected, and I was wondering if it might be possible to create a small utility library to help other developers do this. It seems to me that in the general case, we would be dealing with a Monoid rather than a list of strings. We could have a toMonoid function and then return polyToMonoid value1 value2 ... valueN = (toMonoid value1) `mappend` (toMonoid value2) 'mappend' ... (toMonoid valueN) So anyone who wanted to convert a bunch of values of different types to a Monoid could easily pass them around using polyToMonoid so long as they defined the appropriate toMonoid function. Basically, a generalised list. So I tried writing the following code but GHC said it had undecidable instances. Has this ever been done successfully? class Monoidable a where toMonoid :: Monoid r = a - r polyToMonoid :: (Monoidable a, Monoid r) = a - r polyToMonoid k = polyToMonoid' k mempty class PolyVariadic p where polyToMonoid' :: (Monoidable a, Monoid r) = a - r - p instance Monoid r = PolyVariadic r where polyToMonoid' k ss = (toMonoid k) `mappend` ss instance (Monoidable a, Monoid r) = PolyVariadic (a - r) where polyToMonoid' k ss = (\a - polyToMonoid' k (toMonoid a) `mappend` ss) ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] Re: Polyvariadic functions operating with a monoid
Luke, I had no idea polyvariadic functions would be controversial. Yes, in my original case the function would be trivial: toMonoid k = [toString k] I do prefer the less cluttered look. I think that (poly value1 value2 value3) is easier to follow when the values are all of related types (in my case, all in the same type class). But in the more general Monoid case there would not necessarily be a list result. Eg. sumOf 1 2 3 could also be implemented using a Monoid approach with mempty = 0 and mappend = + Kevin On Oct 3, 9:30 pm, Luke Palmer lrpal...@gmail.com wrote: On Sun, Oct 3, 2010 at 1:26 PM, Luke Palmer lrpal...@gmail.com wrote: On Sun, Oct 3, 2010 at 1:24 AM, Kevin Jardine kevinjard...@gmail.com wrote: I had a situation where I had some related types that all had toString functions. Of course in Haskell, lists all have to be composed of values of exactly the same type, so instead of passing around lists of values with these related types, I created a polyvariadic function polyToString so that I could write: (polyToString value1 value2 value3 ... valueN) which would then become a list of strings: [toString value1, toString value2, ... , toString valueN] First of all, you are not using the monoidal structure of String at all. This trick ought to work for any type whatsoever -- you're just throwing them in a list. Oops, sorry for not reading your message more closely. You were indeed talking about the monoidal structure of list. So... nevermind about this comment. :-P Other than a few brackets, commas, and a repeated identifier (which you can let-bind to shorten), what benefit is it giving you? I strongly recommend against polyvariadic functions. While you get a little bit of notational convenience, you lose composability. There are pains when you try to write a function that takes a polyvariadic function as an argument, or when you try to feed the function values from a list, etc. The mechanisms to create polyvariadic functions are brittle and hacky (eg. you cannot have a polymorphic return type, as you want in this case). Since all your values are known statically, I would recommend biting the bullet and doing it the way you were doing it. [ s value1, s value2, s value3, ... ] where s x = toString x (I had to eta expand s so that I didn't hit the monomorphism restriction) When you want to be passing around heterogeneous lists, it usually works to convert them before you put them in the list, like you were doing. I finally figured out how to do this, but it was a bit harder to figure this out than I expected, and I was wondering if it might be possible to create a small utility library to help other developers do this. It seems to me that in the general case, we would be dealing with a Monoid rather than a list of strings. We could have a toMonoid function and then return polyToMonoid value1 value2 ... valueN = (toMonoid value1) `mappend` (toMonoid value2) 'mappend' ... (toMonoid valueN) So anyone who wanted to convert a bunch of values of different types to a Monoid could easily pass them around using polyToMonoid so long as they defined the appropriate toMonoid function. Basically, a generalised list. So I tried writing the following code but GHC said it had undecidable instances. Has this ever been done successfully? class Monoidable a where toMonoid :: Monoid r = a - r polyToMonoid :: (Monoidable a, Monoid r) = a - r polyToMonoid k = polyToMonoid' k mempty class PolyVariadic p where polyToMonoid' :: (Monoidable a, Monoid r) = a - r - p instance Monoid r = PolyVariadic r where polyToMonoid' k ss = (toMonoid k) `mappend` ss instance (Monoidable a, Monoid r) = PolyVariadic (a - r) where polyToMonoid' k ss = (\a - polyToMonoid' k (toMonoid a) `mappend` ss) ___ Haskell-Cafe mailing list haskell-c...@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe ___ Haskell-Cafe mailing list haskell-c...@haskell.orghttp://www.haskell.org/mailman/listinfo/haskell-cafe ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] Polymorphic record field?
I have an almost finished Haskell program and I discovered that I needed to change the type of one record field. The problem is that the new type is polymorphic. Being new to Haskell, I simply changed: data MyStruct = MyStruct {myField :: myType} to data MyStruct = MyStruct {myField :: MyTypeClass a = a} and then ended up in a maze of compiler messages about Rank N types and Inferred type is less polymorphic than expected. Upon Googling for this issue, I have discovered that Haskell records do not support polymorphic types and that there is a large literature about options to fix this. Although the literature is interesting, what I am looking for right now is a simple fix. I really don't want to have to rewrite all the many type and value references to MyStruct in my code. Is there a way to redefine the definition of MyStruct without changing any of my other code? If I have to change the way myField is accessed, I can handle that. What I don't really want to do is change the type signature of functions that take MyStruct parameters (of which there are many). Is this possible? What is the simplest way to do this? Kevin ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] Re: Polymorphic record field?
OK, thanks for this advice. The type definition compiles, but when I try to actually access myField, the compiler says: Cannot use record selector `myField' as a function due to escaped type variables Probable fix: use pattern-matching syntax instead So I took the hint and wrote a new pattern matching accessor function: getMyField (MyStruct value) = value and I get: Inferred type is less polymorphic than expected Quantified type variable `a' escapes When checking an existential match that binds value :: a Any further suggestions? On Sep 26, 1:09 pm, Daniel Fischer daniel.is.fisc...@web.de wrote: On Sunday 26 September 2010 12:53:46, Michael Snoyman wrote: data MyStruct = forall a. MyTypeClass a = MyStruct {myField :: a} Note that that requires {-# LANGUAGE ExistentialQuantification #-} ___ Haskell-Cafe mailing list haskell-c...@haskell.orghttp://www.haskell.org/mailman/listinfo/haskell-cafe ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] Re: Polymorphic record field?
OK, I have a solution. Ugly, but it compiles. MyStruct actually has quite a few fields but I only need to access the polymorphic field 4 times. So for the functions that needed that I wrote: f myS@(MyStruct value _ _ _ ) and then could use value. I could then use the usual record accessors on myS to get the other (non-polymorphic) data. I guess that is what GHC was hinting at when it suggested pattern matching. That is, pattern matching could extract a value that no functions are apparently allowed to touch. All head spinning to me. Thanks for the (as always) fast and useful advice! Kevin On Sep 26, 2:00 pm, Kevin Jardine kevinjard...@gmail.com wrote: OK, thanks for this advice. The type definition compiles, but when I try to actually access myField, the compiler says: Cannot use record selector `myField' as a function due to escaped type variables Probable fix: use pattern-matching syntax instead So I took the hint and wrote a new pattern matching accessor function: getMyField (MyStruct value) = value and I get: Inferred type is less polymorphic than expected Quantified type variable `a' escapes When checking an existential match that binds value :: a Any further suggestions? On Sep 26, 1:09 pm, Daniel Fischer daniel.is.fisc...@web.de wrote: On Sunday 26 September 2010 12:53:46, Michael Snoyman wrote: data MyStruct = forall a. MyTypeClass a = MyStruct {myField :: a} Note that that requires {-# LANGUAGE ExistentialQuantification #-} ___ Haskell-Cafe mailing list haskell-c...@haskell.orghttp://www.haskell.org/mailman/listinfo/haskell-cafe ___ Haskell-Cafe mailing list haskell-c...@haskell.orghttp://www.haskell.org/mailman/listinfo/haskell-cafe ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] Re: Polymorphic record field?
Hi Michael, Yes, that does compile! Much less ugly and does not expose the internal bits of MyStruct. Thanks. Kevin On Sep 26, 2:26 pm, Michael Snoyman mich...@snoyman.com wrote: How about f myS@(MyStruct { myField = value }) ? On Sun, Sep 26, 2010 at 2:14 PM, Kevin Jardine kevinjard...@gmail.com wrote: OK, I have a solution. Ugly, but it compiles. MyStruct actually has quite a few fields but I only need to access the polymorphic field 4 times. So for the functions that needed that I wrote: f myS@(MyStruct value _ _ _ ) and then could use value. I could then use the usual record accessors on myS to get the other (non-polymorphic) data. I guess that is what GHC was hinting at when it suggested pattern matching. That is, pattern matching could extract a value that no functions are apparently allowed to touch. All head spinning to me. Thanks for the (as always) fast and useful advice! Kevin On Sep 26, 2:00 pm, Kevin Jardine kevinjard...@gmail.com wrote: OK, thanks for this advice. The type definition compiles, but when I try to actually access myField, the compiler says: Cannot use record selector `myField' as a function due to escaped type variables Probable fix: use pattern-matching syntax instead So I took the hint and wrote a new pattern matching accessor function: getMyField (MyStruct value) = value and I get: Inferred type is less polymorphic than expected Quantified type variable `a' escapes When checking an existential match that binds value :: a Any further suggestions? On Sep 26, 1:09 pm, Daniel Fischer daniel.is.fisc...@web.de wrote: On Sunday 26 September 2010 12:53:46, Michael Snoyman wrote: data MyStruct = forall a. MyTypeClass a = MyStruct {myField :: a} Note that that requires {-# LANGUAGE ExistentialQuantification #-} ___ Haskell-Cafe mailing list haskell-c...@haskell.orghttp://www.haskell.org/mailman/listinfo/haskell-cafe ___ Haskell-Cafe mailing list haskell-c...@haskell.orghttp://www.haskell.org/mailman/listinfo/haskell-cafe ___ Haskell-Cafe mailing list haskell-c...@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe ___ Haskell-Cafe mailing list haskell-c...@haskell.orghttp://www.haskell.org/mailman/listinfo/haskell-cafe ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] Re: Scraping boilerplate deriving?
Hi Malcolm, In this case, I am counting on GHC's {-# LANGUAGE GeneralizedNewtypeDeriving #-} feature to derive the instances for the classes I am including in the deriving clause. So perhaps portability is not a big issue here in any case. I do think that defObj(MyType) looks a bit cleaner than $(defObj MyType) so I am starting to lean back towards the CPP solution after all. CPP is not always the best option, but perhaps it is in this case. Kevin On Sep 15, 10:31 am, Malcolm Wallace malcolm.wall...@me.com wrote: That's what I had originally. However, some people have made critical comments about CPP macros on this list and I thought that TH was considered the better option. I was one of those people advising against the use of CPP macros. However, Template Haskell is ghc-only, and is unlikely ever to be implemented by any other Haskell compiler. Thus CPP, for all its faults, may be the better solution here, simply because it is portable. (I also note in passing that ghc's core libraries themselves use exactly this kind of CPP macro to generate lots of tedious boilerplate.) Regards, Malcolm ___ Haskell-Cafe mailing list haskell-c...@haskell.orghttp://www.haskell.org/mailman/listinfo/haskell-cafe ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] Re: Scraping boilerplate deriving?
Hi Ben, Good point! I can confirm that it does compile under GHC 6.12. So really the same number of characters either way. Kevin On Sep 15, 4:49 pm, Ben Millwood hask...@benmachine.co.uk wrote: On Wed, Sep 15, 2010 at 2:11 PM, Kevin Jardine kevinjard...@gmail.com wrote: I do think that defObj(MyType) looks a bit cleaner than $(defObj MyType) I believe as of GHC 6.12 you no longer need the $() around top-level splices. So that would just be: defObj MyType ___ Haskell-Cafe mailing list haskell-c...@haskell.orghttp://www.haskell.org/mailman/listinfo/haskell-cafe ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] Scraping boilerplate deriving?
I have a set of wrapper newtypes that are always of the same format: newtype MyType = MyType Obj deriving (A,B,C,D) where Obj, A, B, C, and D are always the same. Only MyType varies. A, B, C, and D are automagically derived by GHC using the {-# LANGUAGE GeneralizedNewtypeDeriving #-} feature. I would like to use some macro system (perhaps Template Haskell?) to reduce this to something like defObj MyType I've read through some Template Haskell documentation and examples, but I find it intimidatingly hard to follow. Does anyone has some code suggestions or pointers to something similar? Alternatively, is there any way in standard Haskell to define some kind of union class: U = (A, B, C, D) and then using newtype MyType = MyType Obj deriving U which would at least be shorter? ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] Re: Scraping boilerplate deriving?
I supposed the simple solution might be CPP: #define defObj(NAME) newtype NAME = NAME Obj deriving (A,B,C,D) and then use defObj (MyType) I have heard some people, however, say that CPP macros are horrible in Haskell, so is there a better solution? Kevin On Sep 14, 10:34 am, Miguel Mitrofanov miguelim...@yandex.ru wrote: Sorry, got stupid today. Won't help. 14.09.2010 12:29, Miguel Mitrofanov пишет: class (A x, B x, C x, D x) = U x ? 14.09.2010 12:24, Kevin Jardine пишет: I have a set of wrapper newtypes that are always of the same format: newtype MyType = MyType Obj deriving (A,B,C,D) where Obj, A, B, C, and D are always the same. Only MyType varies. A, B, C, and D are automagically derived by GHC using the {-# LANGUAGE GeneralizedNewtypeDeriving #-} feature. I would like to use some macro system (perhaps Template Haskell?) to reduce this to something like defObj MyType I've read through some Template Haskell documentation and examples, but I find it intimidatingly hard to follow. Does anyone has some code suggestions or pointers to something similar? Alternatively, is there any way in standard Haskell to define some kind of union class: U = (A, B, C, D) and then using newtype MyType = MyType Obj deriving U which would at least be shorter? ___ Haskell-Cafe mailing list haskell-c...@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe ___ Haskell-Cafe mailing list haskell-c...@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe ___ Haskell-Cafe mailing list haskell-c...@haskell.orghttp://www.haskell.org/mailman/listinfo/haskell-cafe ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] Re: Scraping boilerplate deriving?
Thanks Serguey! The library code compiles, but when I try to use it in client code: a. I get: Not in scope: type constructor or class 'A' and even stranger, b. GHC cannot find any of my code after the $(mkNewType A) and claims that all the functions I defined there are also not in scope. Any ideas? The CPP solution works but Template Haskell is definitely cooler, so it would be great to get this to work! Kevin On Sep 14, 2:29 pm, Zefirov sergu...@gmail.com wrote: 2010/9/14 Kevin Jardine kevinjard...@gmail.com: I would like to use some macro system (perhaps Template Haskell?) to reduce this to something like defObj MyType I've read through some Template Haskell documentation and examples, but I find it intimidatingly hard to follow. Does anyone has some code suggestions or pointers to something similar? The solutions first: - {-# LANGUAGE TemplateHaskell #-} module T(mkNewType) where import Language.Haskell.TH decls = [d|newtype TempDecl = TempDecl Int deriving (Eq,Ord,Show)|] decl = do [d] - decls runIO $ print d -- just to show inetrnals return d mkNewType :: String - Q [Dec] mkNewType n = do d - decl let name = mkName n return $ (\x - [x]) $ case d of (NewtypeD cxt _ argvars (NormalC _ args) derivings) - NewtypeD cxt name argvars (NormalC name args) derivings -- I took perfectly valid declaration, dissected it using case analysis and changed relevant parts. And an example client: - {-# LANGUAGE TemplateHaskell #-} import T $(mkNewType A) - It all work together. I studied how to use Template Haskell that way: I obtained declarations of what I need, printed them and looked through documentation for relevant data types and constructors. It's not harder that any other library in Haskell, actually. ___ Haskell-Cafe mailing list haskell-c...@haskell.orghttp://www.haskell.org/mailman/listinfo/haskell-cafe ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] Re: Scraping boilerplate deriving?
Hmm - It seems to work if the code is defined before my main function and not after it. Does this have to do with TH being part of the compile process and so the order matters? Kevin On Sep 14, 6:03 pm, Kevin Jardine kevinjard...@gmail.com wrote: Thanks Serguey! The library code compiles, but when I try to use it in client code: a. I get: Not in scope: type constructor or class 'A' and even stranger, b. GHC cannot find any of my code after the $(mkNewType A) and claims that all the functions I defined there are also not in scope. Any ideas? The CPP solution works but Template Haskell is definitely cooler, so it would be great to get this to work! Kevin On Sep 14, 2:29 pm, Zefirov sergu...@gmail.com wrote: 2010/9/14 Kevin Jardine kevinjard...@gmail.com: I would like to use some macro system (perhaps Template Haskell?) to reduce this to something like defObj MyType I've read through some Template Haskell documentation and examples, but I find it intimidatingly hard to follow. Does anyone has some code suggestions or pointers to something similar? The solutions first: - {-# LANGUAGE TemplateHaskell #-} module T(mkNewType) where import Language.Haskell.TH decls = [d|newtype TempDecl = TempDecl Int deriving (Eq,Ord,Show)|] decl = do [d] - decls runIO $ print d -- just to show inetrnals return d mkNewType :: String - Q [Dec] mkNewType n = do d - decl let name = mkName n return $ (\x - [x]) $ case d of (NewtypeD cxt _ argvars (NormalC _ args) derivings) - NewtypeD cxt name argvars (NormalC name args) derivings -- I took perfectly valid declaration, dissected it using case analysis and changed relevant parts. And an example client: - {-# LANGUAGE TemplateHaskell #-} import T $(mkNewType A) - It all work together. I studied how to use Template Haskell that way: I obtained declarations of what I need, printed them and looked through documentation for relevant data types and constructors. It's not harder that any other library in Haskell, actually. ___ Haskell-Cafe mailing list haskell-c...@haskell.orghttp://www.haskell.org/mailman/listinfo/haskell-cafe ___ Haskell-Cafe mailing list haskell-c...@haskell.orghttp://www.haskell.org/mailman/listinfo/haskell-cafe ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] Re: Scraping boilerplate deriving?
OK, thanks for everyone's help! Serguey's code works very well now. Kevin On Sep 14, 6:14 pm, Erik Hesselink hessel...@gmail.com wrote: Yes, if you use template haskell, all top level functions and values have to be defined before you use them. Erik On Tue, Sep 14, 2010 at 18:11, Kevin Jardine kevinjard...@gmail.com wrote: Hmm - It seems to work if the code is defined before my main function and not after it. Does this have to do with TH being part of the compile process and so the order matters? Kevin On Sep 14, 6:03 pm, Kevin Jardine kevinjard...@gmail.com wrote: Thanks Serguey! The library code compiles, but when I try to use it in client code: a. I get: Not in scope: type constructor or class 'A' and even stranger, b. GHC cannot find any of my code after the $(mkNewType A) and claims that all the functions I defined there are also not in scope. Any ideas? The CPP solution works but Template Haskell is definitely cooler, so it would be great to get this to work! Kevin On Sep 14, 2:29 pm, Zefirov sergu...@gmail.com wrote: 2010/9/14 Kevin Jardine kevinjard...@gmail.com: I would like to use some macro system (perhaps Template Haskell?) to reduce this to something like defObj MyType I've read through some Template Haskell documentation and examples, but I find it intimidatingly hard to follow. Does anyone has some code suggestions or pointers to something similar? The solutions first: - {-# LANGUAGE TemplateHaskell #-} module T(mkNewType) where import Language.Haskell.TH decls = [d|newtype TempDecl = TempDecl Int deriving (Eq,Ord,Show)|] decl = do [d] - decls runIO $ print d -- just to show inetrnals return d mkNewType :: String - Q [Dec] mkNewType n = do d - decl let name = mkName n return $ (\x - [x]) $ case d of (NewtypeD cxt _ argvars (NormalC _ args) derivings) - NewtypeD cxt name argvars (NormalC name args) derivings -- I took perfectly valid declaration, dissected it using case analysis and changed relevant parts. And an example client: - {-# LANGUAGE TemplateHaskell #-} import T $(mkNewType A) - It all work together. I studied how to use Template Haskell that way: I obtained declarations of what I need, printed them and looked through documentation for relevant data types and constructors. It's not harder that any other library in Haskell, actually. ___ Haskell-Cafe mailing list haskell-c...@haskell.orghttp://www.haskell.org/mailman/listinfo/haskell-cafe ___ Haskell-Cafe mailing list haskell-c...@haskell.orghttp://www.haskell.org/mailman/listinfo/haskell-cafe ___ Haskell-Cafe mailing list haskell-c...@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe ___ Haskell-Cafe mailing list haskell-c...@haskell.orghttp://www.haskell.org/mailman/listinfo/haskell-cafe ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] Re: Scraping boilerplate deriving?
Hi John, That's what I had originally. However, some people have made critical comments about CPP macros on this list and I thought that TH was considered the better option. What do other people think? Serguey's code is great in any case as it gives me a clearer understanding on how TH works. Kevin On Sep 14, 11:01 pm, John Meacham j...@repetae.net wrote: On Tue, Sep 14, 2010 at 01:24:16AM -0700, Kevin Jardine wrote: I have a set of wrapper newtypes that are always of the same format: newtype MyType = MyType Obj deriving (A,B,C,D) where Obj, A, B, C, and D are always the same. Only MyType varies. A, B, C, and D are automagically derived by GHC using the {-# LANGUAGE GeneralizedNewtypeDeriving #-} feature. I would like to use some macro system (perhaps Template Haskell?) to reduce this to something like defObj MyType How about the straightforward? {-# LANGUAGE CPP #-} #define defObj(t) newtype t = t Obj deriving (A,B,C,D) defObj(Foo) defObj(Bar) It has the advantage of being (de facto) portable. John -- John Meacham - ⑆repetae.net⑆john⑈ -http://notanumber.net/ ___ Haskell-Cafe mailing list haskell-c...@haskell.orghttp://www.haskell.org/mailman/listinfo/haskell-cafe ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] Re: Unwrapping newtypes
Hi Ertugrul, My goal was to find a way to define all that was needed using Haskell's automatic instance deriving mechanism. Haskell can automatically derive Foldable, which is why I was looking at that. However, that requires writing two lines for each wrapper newtype to get around the kind problem. I wanted one line. Fortunately, {-# LANGUAGE GeneralizedNewtypeDeriving #-} gives me what I want now that I know how it works! I agree that the Foldable solution was a bit of a kludge. Kevin On Sep 9, 3:57 am, Ertugrul Soeylemez e...@ertes.de wrote: Kevin Jardine kevinjard...@gmail.com wrote: I have a generic object that I want to wrap in various newtypes to better facilitate type checking. For example, newtype Blog = Blog Obj newtype Comment = Comment Obj newtype User = User Obj Unlike Obj itself, whose internal structure is hidden in a library module, the newtype wrappings are purely to facilitate type checking. It is no secret that each is just a wrapper around Obj. It is obvious how to construct the various wrapper objects. It is not so obvious how to extract the Obj they contain in a reasonably generic way however. What I want is a getObj function that works on all of them. Of course this could work if someone using the library wrote an instance for each wrapper object: instance GetObject Blog where getObj (Blog obj) = obj but this is a pain in the neck to write for each newtype. Simple solution: data ObjContent = Blah data Obj = Blog { getObj :: !ObjContent } | Comment { getObj :: !ObjContent } | User { getObj :: !ObjContent } With your GetObject class this even becomes extensible: instance GetObject Obj where getObject = getObj data OtherType = OtherType ObjContent instance GetObject OtherType where getObject (OtherType obj) = obj I discovered that Foldable defines a handy toList function that extracts content from generic Foldable structures. So that I could write: toObj :: Foldable thing = thing Obj - Obj toObj w = head $ toList w Slightly kludgy but it works. But it's not what you are looking for. You are confusing constructor types with type kinds. Foldable expects a type of kind * - *, which isn't quite what you want. Also I would consider this to be abuse. Also from a complexity standpoint it's nothing different from your GetObject class anyway. You still need to write the instances. Greets, Ertugrul -- nightmare = unsafePerformIO (getWrongWife = sex)http://ertes.de/ ___ Haskell-Cafe mailing list haskell-c...@haskell.orghttp://www.haskell.org/mailman/listinfo/haskell-cafe ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] Re: Unwrapping newtypes
Hi Ertugrul, if you look back earlier in this thread, you'll see that {-# LANGUAGE GeneralizedNewtypeDeriving #-} allows me to write genuine one line definitions for each wrapper type. Eg. newtype Blog = Blog Obj deriving ToObj There is no need to code the instances as GHC will do that for you. Figuring out how to avoid writing the instances was the point of my original post. Kevin On Sep 9, 11:10 am, Ertugrul Soeylemez e...@ertes.de wrote: Kevin Jardine kevinjard...@gmail.com wrote: My goal was to find a way to define all that was needed using Haskell's automatic instance deriving mechanism. Haskell can automatically derive Foldable, which is why I was looking at that. However, that requires writing two lines for each wrapper newtype to get around the kind problem. I wanted one line. There: newtype Blog = Blog { getBlogObj :: Obj } newtype Comment = Comment { getCommentObj :: Obj } newtype User = User { getUserObj :: Obj } class GetObject a where getObject :: a - Obj instance GetObject Blog where getObject = getBlogObject instance GetObject Comment where getObject = getCommentObject instance GetObject User where getObject = getUserObject You shouldn't abuse Foldable for this purpose, unless you really mean it. I agree that the Foldable solution was a bit of a kludge. And not necessary either. Greets, Ertugrul -- nightmare = unsafePerformIO (getWrongWife = sex)http://ertes.de/ ___ Haskell-Cafe mailing list haskell-c...@haskell.orghttp://www.haskell.org/mailman/listinfo/haskell-cafe ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] Unwrapping newtypes
I have a generic object that I want to wrap in various newtypes to better facilitate type checking. For example, newtype Blog = Blog Obj newtype Comment = Comment Obj newtype User = User Obj Unlike Obj itself, whose internal structure is hidden in a library module, the newtype wrappings are purely to facilitate type checking. It is no secret that each is just a wrapper around Obj. It is obvious how to construct the various wrapper objects. It is not so obvious how to extract the Obj they contain in a reasonably generic way however. What I want is a getObj function that works on all of them. Of course this could work if someone using the library wrote an instance for each wrapper object: instance GetObject Blog where getObj (Blog obj) = obj but this is a pain in the neck to write for each newtype. I discovered that Foldable defines a handy toList function that extracts content from generic Foldable structures. So that I could write: toObj :: Foldable thing = thing Obj - Obj toObj w = head $ toList w Slightly kludgy but it works. Even better, recent versions of GHC will allow you to automatically derive Foldable. Unfortunately, newtype Blog = Blog Obj deriving Foldable returns a kind error. What does work is: newtype BlogF a = Blog a deriving Foldable type Blog = BlogF Obj After having spent close to a day on this, I am a bit baffled that such a seemingly trivial problem seems so hard to do. I am wondering if I am missing something really, really obvious. Any suggestions? Or is there perhaps a more Haskelly way to place type constraints on a more generic type? Kevin ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] Re: Unwrapping newtypes
Hi Tony, I stared at that specific section for at least half an hour earlier today but could not figure out how it applied in my specific case. The only examples I have see are for deriving Num. Do you have any more detail on how I could use that extension? Kevin On Sep 8, 2:05 pm, Tony Morris tonymor...@gmail.com wrote: I think you might want -XGeneralizedNewtypeDeriving http://haskell.org/ghc/docs/6.12.2/html/users_guide/deriving.html#id6... On 08/09/10 22:01, Kevin Jardine wrote: I have a generic object that I want to wrap in various newtypes to better facilitate type checking. For example, newtype Blog = Blog Obj newtype Comment = Comment Obj newtype User = User Obj Unlike Obj itself, whose internal structure is hidden in a library module, the newtype wrappings are purely to facilitate type checking. It is no secret that each is just a wrapper around Obj. It is obvious how to construct the various wrapper objects. It is not so obvious how to extract the Obj they contain in a reasonably generic way however. What I want is a getObj function that works on all of them. Of course this could work if someone using the library wrote an instance for each wrapper object: instance GetObject Blog where getObj (Blog obj) = obj but this is a pain in the neck to write for each newtype. I discovered that Foldable defines a handy toList function that extracts content from generic Foldable structures. So that I could write: toObj :: Foldable thing = thing Obj - Obj toObj w = head $ toList w Slightly kludgy but it works. Even better, recent versions of GHC will allow you to automatically derive Foldable. Unfortunately, newtype Blog = Blog Obj deriving Foldable returns a kind error. What does work is: newtype BlogF a = Blog a deriving Foldable type Blog = BlogF Obj After having spent close to a day on this, I am a bit baffled that such a seemingly trivial problem seems so hard to do. I am wondering if I am missing something really, really obvious. Any suggestions? Or is there perhaps a more Haskelly way to place type constraints on a more generic type? Kevin ___ Haskell-Cafe mailing list haskell-c...@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe -- Tony Morrishttp://tmorris.net/ ___ Haskell-Cafe mailing list haskell-c...@haskell.orghttp://www.haskell.org/mailman/listinfo/haskell-cafe ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] Re: Unwrapping newtypes
Hi Tony and James, I'm having trouble constructing the ToObj instance. The obvious code: toObj (w o) = o fails with a syntax error. How do I unwrap the value? Kevin On Sep 8, 2:30 pm, James Andrew Cook mo...@deepbondi.net wrote: On Sep 8, 2010, at 8:19 AM, Kevin Jardine wrote: Hi Tony, I stared at that specific section for at least half an hour earlier today but could not figure out how it applied in my specific case. The only examples I have see are for deriving Num. Do you have any more detail on how I could use that extension? Kevin On Sep 8, 2:05 pm, Tony Morris tonymor...@gmail.com wrote: I think you might want -XGeneralizedNewtypeDeriving http://haskell.org/ghc/docs/6.12.2/html/users_guide/deriving.html#id6... On 08/09/10 22:01, Kevin Jardine wrote: I'm not sure if it's what he originally had in mind, but if your Obj class has a ToObj instance (which would be reasonable), then that extension allows your other classes to derive it: newtype Foo = Foo Obj deriving ToObj -- James___ Haskell-Cafe mailing list haskell-c...@haskell.orghttp://www.haskell.org/mailman/listinfo/haskell-cafe ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] Re: Unwrapping newtypes
Ah, I was missing an important piece of the puzzle. If I write: class ToObj a where toObj :: a - Obj instance ToObj Obj where toObj a = a then newtype Blog = Blog Obj deriving ToObj works! Thanks. On Sep 8, 2:36 pm, Kevin Jardine kevinjard...@gmail.com wrote: Hi Tony and James, I'm having trouble constructing the ToObj instance. The obvious code: toObj (w o) = o fails with a syntax error. How do I unwrap the value? Kevin On Sep 8, 2:30 pm, James Andrew Cook mo...@deepbondi.net wrote: On Sep 8, 2010, at 8:19 AM, Kevin Jardine wrote: Hi Tony, I stared at that specific section for at least half an hour earlier today but could not figure out how it applied in my specific case. The only examples I have see are for deriving Num. Do you have any more detail on how I could use that extension? Kevin On Sep 8, 2:05 pm, Tony Morris tonymor...@gmail.com wrote: I think you might want -XGeneralizedNewtypeDeriving http://haskell.org/ghc/docs/6.12.2/html/users_guide/deriving.html#id6... On 08/09/10 22:01, Kevin Jardine wrote: I'm not sure if it's what he originally had in mind, but if your Obj class has a ToObj instance (which would be reasonable), then that extension allows your other classes to derive it: newtype Foo = Foo Obj deriving ToObj -- James___ Haskell-Cafe mailing list haskell-c...@haskell.orghttp://www.haskell.org/mailman/listinfo/haskell-cafe ___ Haskell-Cafe mailing list haskell-c...@haskell.orghttp://www.haskell.org/mailman/listinfo/haskell-cafe ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] Re: Unwrapping newtypes
Thanks Arie, I'm going to make some of my bare Obj functions accept a ToObj typeclass constraint and do the conversions inside there to avoid cluttering up the wrapped object code. Now that I know how to do this I'm going to see what more restructuring I can do to make the difference between wrapped and bare objects less visible (except of course where it should matter). Kevin On Sep 8, 3:44 pm, Arie Peterson ar...@xs4all.nl wrote: On Wed, 8 Sep 2010 05:51:22 -0700 (PDT), Kevin Jardine kevinjard...@gmail.com wrote: Ah, I was missing an important piece of the puzzle. If I write: class ToObj a where toObj :: a - Obj instance ToObj Obj where toObj a = a then newtype Blog = Blog Obj deriving ToObj works! This post http://www.haskell.org/pipermail/libraries/2006-October/005950.html describes a general mini-library for this situation (having a structure-indicating newtype of an underlying type). The 'Unpack' class is a generalised version of your 'ToObj' class. Maybe it is useful to compare (or even use), especially the smart ways in which you can use this class to hide much of the wrapping/unwrapping. Regards, Arie ___ Haskell-Cafe mailing list haskell-c...@haskell.orghttp://www.haskell.org/mailman/listinfo/haskell-cafe ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] Re: ANNOUNCE: text 0.8.0.0, fast Unicode text support
Hi Tako, The issues involved with String, ByteString, Text and a few related libraries were discussed at great length recently in this thread: http://groups.google.com/group/haskell-cafe/browse_thread/thread/52a21cf61ffb21b0/ Basically, Chars are 32 bit integers and Strings are represented as a list of Chars. This is very convenient for small computations but often very inefficient for anything large scale. The String API is also missing various encoding related features. Because of the limitations of String, various alternative libraries have been proposed. Text is one important option. You'll find much more detail on the above referenced thread. Kevin On Sep 1, 8:13 am, Tako Schotanus t...@codejive.org wrote: On Wed, Sep 1, 2010 at 07:14, John Millikin jmilli...@gmail.com wrote: Don't forget, you can always improve the text library yourself. I love to receive patches, requests for improvement, and bug reports. Are there any areas in particular you'd like help with, for either library? I'm happy to assist any effort which will help reduce use of String. As a Haskell noob I'm curious about this statement, is there something intrinsically wrong with String? Or is it more a performance/resource problem when dealing with large amounts of text for example? (Like having to use StringBuilder in Java if you want to avoid the penalty of repeated String allocations when simply concatenating for example) Cheers, -Tako ___ Haskell-Cafe mailing list haskell-c...@haskell.orghttp://www.haskell.org/mailman/listinfo/haskell-cafe ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] Re: Unix emulation
I'd agree with Stephen. I've used MinGW / msys for years and would never consider doing any open source development (especially involving C) without it. In the past, installing it has only taken a few minutes. That still looks to be the case for MinGW but it now appears that msys has been split into a confusing and long list of packages. I think that it needs a standard installer as well (in fact the combined MinGW/msys package needs one standard installer as I think it is rare these days to use one without the other.) Kevin On Aug 23, 8:53 am, Stephen Tetley stephen.tet...@gmail.com wrote: On 23 August 2010 06:12, Erik de Castro Lopo mle...@mega-nerd.com wrote: I'm going to be a bit of a heretic here and suggest that you attack this problem from the other end. How you ask? Install Debian Testing/Unstable with Wine in a VM and cross compile to Windows. No - that's a completely azzback solution. MinGW / MSYS works fine, the problem is solely that the documentation of the install procedure has gone awry, with conflicting and seemingly out of date guides on the mingw.org website. The best solution would be to sign up to the mingw-user mailing list and ask what the currently preferred method is for installing. ___ Haskell-Cafe mailing list haskell-c...@haskell.orghttp://www.haskell.org/mailman/listinfo/haskell-cafe ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] regex-compat on latest Haskell Platform
I'm running Haskel Platform 2010.2.0.0 and attempting to compile with regex-compat under Windows XP. The link stage fails with a number of lines of the form: D:\Program Files\Haskell Platform\2010.2.0.0\lib\extralibs\regex- posix-0.94.2\ghc-6.12.3/libHSregex-posix-0.94.2.a(Wrap.o):fake:(.text +0x493): undefined reference to `regerror' I have googled for a solution but cannot see a fix anywhere. Any suggestions? Kevin ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] Re: regex-compat on latest Haskell Platform
I have found this project: http://gnuwin32.sourceforge.net/packages/regex.htm and downloaded the DLL. But just placing this in Windows/System32 does nothing. Kevin On Aug 17, 11:00 am, Kevin Jardine kevinjard...@gmail.com wrote: I'm running Haskel Platform 2010.2.0.0 and attempting to compile with regex-compat under Windows XP. The link stage fails with a number of lines of the form: D:\Program Files\Haskell Platform\2010.2.0.0\lib\extralibs\regex- posix-0.94.2\ghc-6.12.3/libHSregex-posix-0.94.2.a(Wrap.o):fake:(.text +0x493): undefined reference to `regerror' I have googled for a solution but cannot see a fix anywhere. Any suggestions? Kevin ___ Haskell-Cafe mailing list haskell-c...@haskell.orghttp://www.haskell.org/mailman/listinfo/haskell-cafe ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] Re: regex-compat on latest Haskell Platform
I was assuming that regex would work properly with the latest Haskell Platform so I haven't attempted to re-install it. However as I mentioned above, attempting to compile a program that uses regex fails with linker errors on my Windows XP machine. Any ideas on how I can fix this problem? Kevin On Aug 17, 1:35 pm, Stephen Tetley stephen.tet...@gmail.com wrote: Hi Kevin Are you trying to compile a program using regex-posix or compiling and installing an update of regex-posix (which is already in the Platform)? If you are compiling a program that uses regex-posix, you shouldn't need to install other DLLs as the relevant libraries (.a and .o files) are distributed with the Platform. For what its worth, Regex-posix worked fine with Platform 2009.2.0.2. I follow GHC releases rather than Platform ones, so I don't know about later versions. Best wishes Stephen ___ Haskell-Cafe mailing list haskell-c...@haskell.orghttp://www.haskell.org/mailman/listinfo/haskell-cafe ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] Re: regex-compat on latest Haskell Platform
I'm running cabal install for the program that uses regex-compat. runhaskell doesn't work because compiling the code requires library information in the cabal file. I've also tried to run something similar using ghci on the same machine and it also fails with a similar error. Kevin On Aug 17, 1:54 pm, Stephen Tetley stephen.tet...@gmail.com wrote: On 17 August 2010 12:45, Kevin Jardine kevinjard...@gmail.com wrote: I was assuming that regex would work properly with the latest Haskell Platform so I haven't attempted to re-install it. Yes - its wise not to upgrade platform components, especially on Windows. However as I mentioned above, attempting to compile a program that uses regex fails with linker errors on my Windows XP machine. Any ideas on how I can fix this problem? What command are you using for ghc? With Platform 2009.2.0.2, I've tested a simple regex example with just / ghc --make ModuleName / - it compiled and ran under both MinGW and the Windows prompt. Also does can you launch with runhaskell on the Main module? ___ Haskell-Cafe mailing list haskell-c...@haskell.orghttp://www.haskell.org/mailman/listinfo/haskell-cafe ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] Re: String vs ByteString
On Aug 17, 1:55 pm, Tako Schotanus t...@codejive.org wrote: I'll repeat here that in my opinion a Text package should be good at handling text, human text, from whatever country. If I need to handle large streams of ASCII I'll use something else. I would mostly agree. However, a key use case for Text in my view is web applications. A typical web page is composed of mostly ASCII tags interspersed with (often) non-ASCII content. I would argue that it is crucial that Text work well in this case. Well in this context means efficient enough to be used as the standard format for most web applications. I do not know enough about text algorithms to recommend a more detailed meaning for efficient enough. Kevin ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] Re: regex-compat on latest Haskell Platform
No, it's my own code. But in ghci even the simplest =~ fails on my machine. Here's a complete transcript: ghci GHCi, version 6.12.3: http://www.haskell.org/ghc/ :? for help Loading package ghc-prim ... linking ... done. Loading package integer-gmp ... linking ... done. Loading package base ... linking ... done. Loading package ffi-1.0 ... linking ... done. Prelude :mod Text.Regex.Posix Prelude Text.Regex.Posix hi =~ hi :: Bool Loading package array-0.3.0.1 ... linking ... done. Loading package bytestring-0.9.1.7 ... linking ... done. Loading package containers-0.3.0.0 ... linking ... done. Loading package syb-0.1.0.2 ... linking ... done. Loading package base-3.0.3.2 ... linking ... done. Loading package mtl-1.1.0.2 ... linking ... done. Loading package regex-base-0.93.2 ... linking ... done. Loading package regex-posix-0.94.2 ... linking ... interactive: D: \PROGRA~1\HA SKEL~1\201020~1.0\lib\extralibs\regex-posix-0.94.2\ghc-6.12.3\HSregex- posix-0.94 .2.o: unknown symbol `_regerror' : unable to load package `regex-posix-0.94.2' Prelude Text.Regex.Posix On Aug 17, 2:05 pm, Stephen Tetley stephen.tet...@gmail.com wrote: Hi Kevin Is it a library on Hackage? I'll take a look if the dependencies aren't too deep... ___ Haskell-Cafe mailing list haskell-c...@haskell.orghttp://www.haskell.org/mailman/listinfo/haskell-cafe ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] Re: regex-compat on latest Haskell Platform
yep now I see it: http://trac.haskell.org/haskell-platform/ticket/137 Next time I'll check the bug tracker as well as Google before posting here! Thanks. Kevin On Aug 17, 2:37 pm, Stephen Tetley stephen.tet...@gmail.com wrote: Hi Kevin I've just installed Platform-2010.2.0.0 and I'm getting the symbol error on the file that I could compile with Platform2009.2.0.2. So I'd say it is a bug with the Platform, also it looks like the error was acknowledged on the Platform mailing list last week. $ /c/ghc/HP/2010.2.0.0/bin/ghc --make OutlineGrep.lhs [1 of 1] Compiling Main ( OutlineGrep.lhs, OutlineGrep.o ) Linking OutlineGrep.exe ... C:\ghc\HP\2010.2.0.0\lib\extralibs\regex-posix-0.94.2\ghc-6.12.3/libHSregex-posix-0.94.2.a(Wrap.o):f ake:(.text+0x493): undefined reference to `regerror' C:\ghc\HP\2010.2.0.0\lib\extralibs\regex-posix-0.94.2\ghc-6.12.3/libHSregex-posix-0.94.2.a(Wrap.o):f ake:(.text+0x4e7): undefined reference to `regerror' etc. ___ Haskell-Cafe mailing list haskell-c...@haskell.orghttp://www.haskell.org/mailman/listinfo/haskell-cafe ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] Re: regex-compat on latest Haskell Platform
The bug tracker recommended just installing from Hackage so with some trepidation I typed: cabal install regex-posix and everything now works as expected! So sorry for the waste of bandwidth. At least this thread is now in Google. Kevin On Aug 17, 3:06 pm, Kevin Jardine kevinjard...@gmail.com wrote: yep now I see it: http://trac.haskell.org/haskell-platform/ticket/137 Next time I'll check the bug tracker as well as Google before posting here! Thanks. Kevin On Aug 17, 2:37 pm, Stephen Tetley stephen.tet...@gmail.com wrote: Hi Kevin I've just installed Platform-2010.2.0.0 and I'm getting the symbol error on the file that I could compile with Platform2009.2.0.2. So I'd say it is a bug with the Platform, also it looks like the error was acknowledged on the Platform mailing list last week. $ /c/ghc/HP/2010.2.0.0/bin/ghc --make OutlineGrep.lhs [1 of 1] Compiling Main ( OutlineGrep.lhs, OutlineGrep.o ) Linking OutlineGrep.exe ... C:\ghc\HP\2010.2.0.0\lib\extralibs\regex-posix-0.94.2\ghc-6.12.3/libHSregex-posix-0.94.2.a(Wrap.o):f ake:(.text+0x493): undefined reference to `regerror' C:\ghc\HP\2010.2.0.0\lib\extralibs\regex-posix-0.94.2\ghc-6.12.3/libHSregex-posix-0.94.2.a(Wrap.o):f ake:(.text+0x4e7): undefined reference to `regerror' etc. ___ Haskell-Cafe mailing list haskell-c...@haskell.orghttp://www.haskell.org/mailman/listinfo/haskell-cafe ___ Haskell-Cafe mailing list haskell-c...@haskell.orghttp://www.haskell.org/mailman/listinfo/haskell-cafe ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] Re: regex-compat on latest Haskell Platform
Mikhail and Don, All I needed to do was to type: cabal install regex-posix and everything now works as expected. As Mikhail also mentioned this problem is already in the Haskell Platform bug tracker. Kevin On Aug 18, 5:17 am, Don Stewart d...@galois.com wrote: kevinjardine: I'm running Haskel Platform 2010.2.0.0 and attempting to compile with regex-compat under Windows XP. The link stage fails with a number of lines of the form: D:\Program Files\Haskell Platform\2010.2.0.0\lib\extralibs\regex- posix-0.94.2\ghc-6.12.3/libHSregex-posix-0.94.2.a(Wrap.o):fake:(.text +0x493): undefined reference to `regerror' I have googled for a solution but cannot see a fix anywhere. Looks like possibly missing regex.h header files (from the regex C library) On Windows? -- Don ___ Haskell-Cafe mailing list haskell-c...@haskell.orghttp://www.haskell.org/mailman/listinfo/haskell-cafe ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] Re: A cabal odyssey
The latest version of the Haskell Platform is Haskell Platform 2010.2.0.0. However, even with the latest version, cabal install cabal-install installs cabal in the wrong place (not in extralibs/bin) under Windows at least so it is impossible to upgrade cabal. Having said that perhaps it is for the best as I have had bad experiences upgrading bits of the Haskell Platform. It is probably safer just to be satisfied with whatever comes with the latest version of the Platform and wait patiently for the next release. Kevin On Aug 16, 9:27 pm, Andrew Coppin andrewcop...@btinternet.com wrote: And so today, just for giggles, I tried to get Sifflet to work. Along the way, I encountered a number of... glitches, if you will. First of all, I tried to get it to work on Windows. I fired up a new Windows VM and installed Haskell Platform 2010.1.0.0. It seems that (finally) this includes the cabal-install tool, which is nice. It seems it includes cabal-install 0.8.0, so as soon as I tried cabal update, it tells me a new version is available. It claims I just need to cabal install cabal-install (which is amusingly riddle-like). Unfortunately, although doing this *does work*, the new cabal.exe is installed lower down the search path than the existing one, so you still get the old version (unless you manually fiddle with the search path). In fact, it seems that the HP install folder is higher up the search path than the global binary target, which is higher than the local binary target. It seems to me like this ought to be the other way around. The next problem is that cabal install sifflet gets mighty confused and outright fails. Basically it can't figure out how to resolve all the dependencies. It seems that Sifflet demands GTK 0.11.0 (i.e., gtk-0.11.0, pango-0.11.0, glib-0.11.0, etc.) However, Cabal looks at gtk-0.11.0, sees it depends on (say) glib-0.11.*, and wants to use glib-0.11.1 (the latest one). But then Sifflet wants glib-0.11.0, not glib-0.11.1, and it seems Cabal just can't figure out what the heck to do. Which is slightly surprising, really. The solution (of sorts) is to painstakingly resolve the dependencies by hand, by asking Cabal to install the correct packages one at a time in the correct order. (I still love the way Gtk2hs *actually compiles* on Windows now. That's pretty sweet!) That reminds me. What the heck is actually *in* file 126? I don't know why, but compiling file 126 (Graphics.UI.Gtk.Gdk.Cursor) takes up 75% of the entire Gtk2hs build time! What's that all about? Anyway, having finally built Gtk2hs version 0.11.0 successfully, I continued trying to get Sifflet working... only to discover it wants the curl package. And when I ask Cabal to build it, it just retorts that it has a configure script. *sigh* So that's the end of that. I have absolutely no idea why a tool like Sifflet would need access to the Curl library. Presumably this is just another one of those obscure dependency-chasing artifacts that happen from time to time? (After dealing with Linux, I'm used to this kind of weirdness.) OK, so it's only possible to run Sifflet under Linux. Let's give that a try... So I fire up a new OpenSUSE VM. I quickly discovered that gtk seems to want Alex and Happy, but cabal-install is defaulting to doing a local rather than global install, and thereafter it can't find Alex or Happy, even though they're installed. (Yeah, great, thanks for that...) So I rewind the VM, build the latest version of cabal-install, and edit the configuration to do global installs instead of local. The amusing part is, if you sudo cabal install so it has permission to put the installed files into place, it then uses root's configuration file instead. *sigh* Well anyway, I managed to work around that. But... Cabal *still* fails to find Alex or Happy, even though they're now in the search path. Oh, wait. They're in *my* search path. They're not in root's search path. (As per good security practise, root's search path is rather short.) I can pass some CLI switches to tell it where these are, but then gtk2hs-buildtools makes a whole bunch of stuff which Cabal also can't find. Eventually, the easiest thing I could come up with was to do cabal unpack to get a source tree, configure and build as me, and sudo for the install. Except that then it tries to reconfigure...? Wuh? So instead of sudo cabal install, I tried sudo runhaskell Setup install, which works just fine (although obviously it's rather wordy!) So, I manually hold Cabal's hand through the process of building all the 0.11.0 packages one at a time, in a way that it can find all the stuff at configure-time. Gosh this is a faff! Well anyway, it worked. Trips over when I reach Curl, but that's because I need to ask YaST to install the curl-devel package. And, finally, I can build and install Sifflet itself. After 4 hours or so of typing commands, it was nice to do some stuff with my mouse. ;-)
[Haskell-cafe] Re: String vs ByteString
I'm interested to see this kind of open debate on performance, especially about libraries that provide widely used data structures such as strings. One of the more puzzling aspects of Haskell for newbies is the large number of libraries that appear to provide similar/duplicate functionality. The Haskell Platform deals with this to some extent, but it seems to me that if there are new libraries that appear to provide performance boosts over more widely used libraries, it would be best if the new code gets incorporated into the existing more widely used libraries rather than creating more code to maintain / choose from. I think that open debate about performance trade-offs could help consolidate the libraries. Kevin On Aug 13, 4:08 pm, Johan Tibell johan.tib...@gmail.com wrote: On Fri, Aug 13, 2010 at 4:03 PM, Pierre-Etienne Meunier pierreetienne.meun...@gmail.com wrote: Hi, Why don't you use the Data.Rope library ? The asymptotic complexities are way better than those of the ByteString functions. PE For some operations. I'd expect it to be a constant factor slower on average though. -- Johan ___ Haskell-Cafe mailing list haskell-c...@haskell.orghttp://www.haskell.org/mailman/listinfo/haskell-cafe ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] Re: String vs ByteString
This back and forth on performance is great! I often see ByteString used where Text is theoretically more appropriate (eg. the Snap web framework) and it would be good to get these performance issues ironed out so people feel more comfortable using the right tool for the job based upon API rather than performance. Many other languages have two major formats for strings (binary and text) and it would be great if performance improvements for ByteString and Text allowed the same kind of convergence for Haskell. Kevin On Aug 13, 7:53 pm, Bryan O'Sullivan b...@serpentine.com wrote: On Fri, Aug 13, 2010 at 9:55 AM, Daniel Fischer daniel.is.fisc...@web.dewrote: That's an unfortunate example. Using the stringsearch package, substring searching in ByteStrings was considerably faster than in Data.Text in my tests. Interesting. Got a test case so I can repro and fix? :-) ___ Haskell-Cafe mailing list haskell-c...@haskell.orghttp://www.haskell.org/mailman/listinfo/haskell-cafe ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] Re: String vs ByteString
Surely a lot of real world text processing programs are IO intensive? So if there is no native Text IO and everything needs to be read in / written out as ByteString data converted to/from Text this strikes me as a major performance sink. Or is there native Text IO but just not in your example? Kevin On Aug 13, 8:57 pm, Daniel Fischer daniel.is.fisc...@web.de wrote: Just occurred to me, a lot of the difference is due to the fact that text has to convert a ByteString to Text on reading the file, so I timed that by reading the file and counting the chunks, that took text 0.21s for big.txt vs. Data.ByteString.Lazy's 0.01s. So for searching in-memory strings, subtract about 0.032s/MB from the difference - it's still large. ___ Haskell-Cafe mailing list haskell-c...@haskell.orghttp://www.haskell.org/mailman/listinfo/haskell-cafe ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] Re: String vs ByteString
I find it disturbing that a modern programming language like Haskell still apparently forces you to choose between a representation for mostly ASCII text and Unicode. Surely efficient Unicode text should always be the default? And if the Unicode format used by the Text library is not efficient enough then can't that be fixed? Cheers, Kevin On Aug 13, 10:28 pm, Ketil Malde ke...@malde.org wrote: Johan Tibell johan.tib...@gmail.com writes: Here's a rule of thumb: If you have binary data, use Data.ByteString. If you have text, use Data.Text. If you have a large amount of mostly ASCII text, use ByteString, since Data.Text uses twice the storage. Also, ByteString might make more sense if the data is in a byte-oriented encoding, and the cost of encoding and decoding utf-16 would be significant. -k -- If I haven't seen further, it is by standing in the footprints of giants ___ Haskell-Cafe mailing list haskell-c...@haskell.orghttp://www.haskell.org/mailman/listinfo/haskell-cafe ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] Re: String vs ByteString
Hi Don, With respect, I disagree with that approach. Almost every modern programming language has one or at most two standard representations for strings. That includes PHP, Python, Ruby, Perl and many others. The lack of a standard text representation in Haskell has created a crazy patchwork of incompatible libraries requiring explicit and often inefficient conversions to connect them together. I expect Haskell to be higher level than those other languages so that I can ignore the lower level details and focus on the algorithms. But in fact the string issue forces me to deal with lower level details than even PHP requires. I end up with a program littered with ugly pack, unpack, toString, fromString and similar calls. That just doesn't feel right to me. Kevin On Aug 13, 10:39 pm, Don Stewart d...@galois.com wrote: There are many libraries for many purposes. How to pick your string library in Haskell http://blog.ezyang.com/2010/08/strings-in-haskell/ kevinjardine: I find it disturbing that a modern programming language like Haskell still apparently forces you to choose between a representation for mostly ASCII text and Unicode. Surely efficient Unicode text should always be the default? And if the Unicode format used by the Text library is not efficient enough then can't that be fixed? Cheers, Kevin On Aug 13, 10:28�pm, Ketil Malde ke...@malde.org wrote: Johan Tibell johan.tib...@gmail.com writes: Here's a rule of thumb: If you have binary data, use Data.ByteString. If you have text, use Data.Text. If you have a large amount of mostly ASCII text, use ByteString, since Data.Text uses twice the storage. �Also, ByteString might make more sense if the data is in a byte-oriented encoding, and the cost of encoding and decoding utf-16 would be significant. -k -- If I haven't seen further, it is by standing in the footprints of giants ___ Haskell-Cafe mailing list haskell-c...@haskell.orghttp://www.haskell.org/mailman/listinfo/haskell-cafe ___ Haskell-Cafe mailing list haskell-c...@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe ___ Haskell-Cafe mailing list haskell-c...@haskell.orghttp://www.haskell.org/mailman/listinfo/haskell-cafe ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] Re: String vs ByteString
On Aug 14, 2:41 am, Brandon S Allbery KF8NH allb...@ece.cmu.edu wrote: Efficient for what? The most efficient Unicode representation for Latin-derived strings is UTF-8, but the most efficient for CJK is UTF-16. I think that this kind of programming detail should be handled internally (even if necessary by switching automatically from UTF-8 to UTF-16 depending upon the language). I'm using Haskell so that I can write high level code. In my view I should not have to care if the people using my application write in Farsi, Quechua or Tamil. Kevin ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] Re: can Haskell do everyting as we want?
In my experience two of the biggest issues in selecting any language are the pool of potential programmers and the learning curve for the programmers you already have. If you only need two programmers to do a project and they both know Haskell well, then I think Haskell would do almost any job very well. I also think that the pool of potential Haskell programmers is growing. But it is still much smaller than many other languages. I do think that there is a larger learning curve for Haskell than moving from one imperative language (eg. PHP) to another one (eg. Ruby). In my view Haskell programmers are likely to be more productive and produce more correct (and possibly even more efficient) code once they know the language well. Kevin On Aug 4, 4:35 pm, David Leimbach leim...@gmail.com wrote: On Wed, Aug 4, 2010 at 3:16 AM, Alberto G. Corona agocor...@gmail.comwrote: Just to clarify, I mean: Haskell may be seriously addictive. Sounds like a joke, but it is not. I do not recommend it for coding something quick and dirty. I use it for quick and dirty stuff all the time, mainly because what I want is often something that can be broken down into stages of processing, and pure functions are really nice for that. If I know the input is coming from a reliable enough stream (like a unix pipe to stdin) I can use functions like interact to create filters, or parse some input, and produce some output. It's pretty nice. 2010/8/4 Alberto G. Corona agocor...@gmail.com Before entering haskell, please read our disclaimer: http://www.haskell.org/pipermail/haskell-cafe/2010-June/079044.html You've been warned * * 2010/8/4 Zura_ x...@gol.ge As already noted here, Haskell is a general purpose language, but you should take it with a grain of salt. For instance, you can nail with a laptop (provided that you hit the place where a HDD is located), but you prefer a hammer :) One thing is if you do it only for enjoyment, in this case you can even develop 3D shooter game in Haskell, but when it comes to production/real world use, I think it is better to maintain right tool for the right job attitude. Regards, Zura Qi Qi-2 wrote: Is there anyone happen to come into any tasks that haskell is not able to achieve? -- View this message in context: http://old.nabble.com/can-Haskell-do-everyting-as-we-want--tp29341176... Sent from the Haskell - Haskell-Cafe mailing list archive at Nabble.com. ___ Haskell-Cafe mailing list haskell-c...@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe ___ Haskell-Cafe mailing list haskell-c...@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe ___ Haskell-Cafe mailing list haskell-c...@haskell.orghttp://www.haskell.org/mailman/listinfo/haskell-cafe ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] Re: what's the best environment for haskell work?
On Windows, I've used cedit for various projects for years and was delighted to discover that it comes with a Haskell syntax colouring file. See: http://cedit.sourceforge.net/ It supports collections of project files and compiling directly from the editor. I also use Eclipse for (sigh) PHP projects but at least under Windows the Eclipse support available for Haskell appears to be limited. For example the older versions do not appear to have a way to jump immediately to a function definition and I could not get the more recent versions to work at all (Eclipse users, feel free to correct me if I missed something.) Cedit does not have a jump-to-function feature either but it is much smaller and in my experience more stable than Eclipse under Windows. Kevin On Jul 31, 12:07 pm, Rustom Mody rustompm...@gmail.com wrote: Do most people who work with haskell use emacs/vi/eclipse or something else?? Personal Note: I used gofer some 15 years ago. At that time I hacked up a emacs mode (I did not know of any then) along with some changes to gofer to have gofer inside emacs rather than vi inside gofer. Things have got more exciting now -- just trying to catch up!! [Note: My preferrred/default OS is debian-squeeze] ___ Haskell-Cafe mailing list haskell-c...@haskell.orghttp://www.haskell.org/mailman/listinfo/haskell-cafe ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] Re: Can we come out of a monad?
The original poster states that the type of modifiedImage is simply ByteString but given that it calls execState, is that possible? Would it not be State ByteString? Kevin On Jul 30, 9:49 am, Anton van Straaten an...@appsolutions.com wrote: C K Kashyap wrote: In the code here - http://hpaste.org/fastcgi/hpaste.fcgi/view?id=28393#a28393 If I look at the type of modifiedImage, its simply ByteString - but isn't it actually getting into and back out of the state monad? I am of the understanding that once you into a monad, you cant get out of it? Is this breaking the monad scheme? modifiedImage uses the execState function, which has the following type: execState :: State s a - s - s In other words, it applies a State monad value to a state, and returns a new state. Its entire purpose is to run the monad and obtain the resulting state. A monadic value of type State s a is a kind of delayed computation that doesn't do anything until you apply it to a state, using a function like execState or evalState. Once you do that, the computation runs, the monad is evaluated away, and a result is returned. The issue about not being able to escape that (I think) you're referring to applies to the functions within that computation. A State monad computation typically consists of a chain of monadic functions of type (a - State s b) composed using bind (=). A function in that composed chain has to return a monadic value, which constrains the ability of such a function to escape from the monad. Within a monadic function, you may deal directly with states and non-monadic values, and you may run functions like evalState or execState which eliminate monads, but the function still has to return a monadic value in the end, e.g. using return to lift an ordinary value into the monad. Anton ___ Haskell-Cafe mailing list haskell-c...@haskell.orghttp://www.haskell.org/mailman/listinfo/haskell-cafe ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] Re: Can we come out of a monad?
Oops, I should have written IO ByteString as the State stuff is only *inside* execState. But a monad none the less? Kevin On Jul 30, 9:59 am, Kevin Jardine kevinjard...@gmail.com wrote: The original poster states that the type of modifiedImage is simply ByteString but given that it calls execState, is that possible? Would it not be State ByteString? Kevin On Jul 30, 9:49 am, Anton van Straaten an...@appsolutions.com wrote: C K Kashyap wrote: In the code here - http://hpaste.org/fastcgi/hpaste.fcgi/view?id=28393#a28393 If I look at the type of modifiedImage, its simply ByteString - but isn't it actually getting into and back out of the state monad? I am of the understanding that once you into a monad, you cant get out of it? Is this breaking the monad scheme? modifiedImage uses the execState function, which has the following type: execState :: State s a - s - s In other words, it applies a State monad value to a state, and returns a new state. Its entire purpose is to run the monad and obtain the resulting state. A monadic value of type State s a is a kind of delayed computation that doesn't do anything until you apply it to a state, using a function like execState or evalState. Once you do that, the computation runs, the monad is evaluated away, and a result is returned. The issue about not being able to escape that (I think) you're referring to applies to the functions within that computation. A State monad computation typically consists of a chain of monadic functions of type (a - State s b) composed using bind (=). A function in that composed chain has to return a monadic value, which constrains the ability of such a function to escape from the monad. Within a monadic function, you may deal directly with states and non-monadic values, and you may run functions like evalState or execState which eliminate monads, but the function still has to return a monadic value in the end, e.g. using return to lift an ordinary value into the monad. Anton ___ Haskell-Cafe mailing list haskell-c...@haskell.orghttp://www.haskell.org/mailman/listinfo/haskell-cafe ___ Haskell-Cafe mailing list haskell-c...@haskell.orghttp://www.haskell.org/mailman/listinfo/haskell-cafe ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] Re: Can we come out of a monad?
Or is it possible to call a function in a monad and return a pure result? I think that is what the original poster was asking? I know that unsafePerformIO can do this, but I thought that was a bit of a hack. I'm still trying to understand how monads interact with types so I am interested in this as well. Kevin On Jul 30, 10:11 am, Kevin Jardine kevinjard...@gmail.com wrote: Oops, I should have written IO ByteString as the State stuff is only *inside* execState. But a monad none the less? Kevin On Jul 30, 9:59 am, Kevin Jardine kevinjard...@gmail.com wrote: The original poster states that the type of modifiedImage is simply ByteString but given that it calls execState, is that possible? Would it not be State ByteString? Kevin On Jul 30, 9:49 am, Anton van Straaten an...@appsolutions.com wrote: C K Kashyap wrote: In the code here - http://hpaste.org/fastcgi/hpaste.fcgi/view?id=28393#a28393 If I look at the type of modifiedImage, its simply ByteString - but isn't it actually getting into and back out of the state monad? I am of the understanding that once you into a monad, you cant get out of it? Is this breaking the monad scheme? modifiedImage uses the execState function, which has the following type: execState :: State s a - s - s In other words, it applies a State monad value to a state, and returns a new state. Its entire purpose is to run the monad and obtain the resulting state. A monadic value of type State s a is a kind of delayed computation that doesn't do anything until you apply it to a state, using a function like execState or evalState. Once you do that, the computation runs, the monad is evaluated away, and a result is returned. The issue about not being able to escape that (I think) you're referring to applies to the functions within that computation. A State monad computation typically consists of a chain of monadic functions of type (a - State s b) composed using bind (=). A function in that composed chain has to return a monadic value, which constrains the ability of such a function to escape from the monad. Within a monadic function, you may deal directly with states and non-monadic values, and you may run functions like evalState or execState which eliminate monads, but the function still has to return a monadic value in the end, e.g. using return to lift an ordinary value into the monad. Anton ___ Haskell-Cafe mailing list haskell-c...@haskell.orghttp://www.haskell.org/mailman/listinfo/haskell-cafe ___ Haskell-Cafe mailing list haskell-c...@haskell.orghttp://www.haskell.org/mailman/listinfo/haskell-cafe ___ Haskell-Cafe mailing list haskell-c...@haskell.orghttp://www.haskell.org/mailman/listinfo/haskell-cafe ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] Re: Can we come out of a monad?
I think that these are therefore the responses to the original questions: I am of the understanding that once you into a monad, you cant get out of it? You can run monadic functions and get pure results. So it looks like in that sense you can get out of it. Is this breaking the monad scheme? Apparently not. Although functions that do this for monads that have side effects are unsafe, so use them carefully. Cheers, Kevin On Jul 30, 11:17 am, Anton van Straaten an...@appsolutions.com wrote: On Jul 30, 9:59 am, Kevin Jardine kevinjard...@gmail.com wrote: The original poster states that the type of modifiedImage is simply ByteString but given that it calls execState, is that possible? Would it not be State ByteString? Oops, I should have written IO ByteString as the State stuff is only *inside* execState. But a monad none the less? State is a pure monad that doesn't involve IO. It works by threading a state value through the monadic computation, so old states are discarded and new states are passed on, and no actual mutation is involved. This means there's no need to bring IO into it. If you look at the type signature of execState, you'll see that unless the state type 's' involves IO, the return type can't involve IO. It can help to run little examples of this. Here's a GHCi transcript: Prelude :m Control.Monad.State Prelude Control.Monad.State let addToState :: Int - State Int (); addToState x = do s - get; put (s+x) Prelude Control.Monad.State let mAdd4 = addToState 4 Prelude Control.Monad.State :t mAdd4 m :: State Int () Prelude Control.Monad.State let s = execState mAdd4 2 Prelude Control.Monad.State :t s s :: Int Prelude Control.Monad.State s 6 In the above, addToState is a monadic function that adds its argument x to the current state. mAdd4 is a monadic value that adds 4 to whatever state it's eventually provided with. When execState provides it with an initial state of 2, the monadic computation is run, and the returned result is 6, which is an Int, not a monadic type. Or is it possible to call a function in a monad and return a pure result? I think that is what the original poster was asking? If you use a function like execState (depending on the monad), you can typically run a monadic computation and get a non-monadic result. However, if you're doing that inside a monadic function, you still have to return a value of monadic type - so typically, you use 'return', which lifts a value into the monad. I know that unsafePerformIO can do this, but I thought that was a bit of a hack. IO is a special monad which has side effects. unsafePerformIO is just one of the functions that can run IO actions, but because the monad has side effects, this is unsafe in general. With a pure monad like State, there's no such issue. Anton ___ Haskell-Cafe mailing list haskell-c...@haskell.orghttp://www.haskell.org/mailman/listinfo/haskell-cafe ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] Re: Can we come out of a monad?
I think that we are having a terminology confusion here. For me, a pure function is one that does not operate inside a monad. Eg. ++, map, etc. It was at one point my belief that although code in monads could call pure functions, code in pure functions could not call functions that operated inside a monad. I was then introduced to functions such as execState and unsafePerformIO which appear to prove that my original belief was false. Currently I am in a state of deep confusion, but that is OK, because it means that I am learning something new! Kevin On Jul 30, 11:55 am, Anton van Straaten an...@appsolutions.com wrote: Kevin Jardine wrote: I think that these are therefore the responses to the original questions: I am of the understanding that once you into a monad, you cant get out of it? You can run monadic functions and get pure results. Some clarifications: First, many monads (including State) are completely pure in a referential transparency sense, so the issue we're discussing is not a question of whether results are pure (in general) but rather whether they're monadic or not, i.e. whether the type of a result is something like Monad m = m a, or just a. Second, what I was calling a monadic function is a function of type: Monad m = a - m b These are the functions that bind (=) composes. When you apply these functions to a value of type a, you always get a monadic value back of type m b, because the type says so. These functions therefore *cannot* do anything to escape the monad, and by the same token, a chain of functions composed with bind, or the equivalent sequence of statements in a 'do' expression, cannot escape the monad. It is only the monadic values (a.k.a. actions) of type m b that you can usually run using a runner function specific to the monad in question, such as execState (or unsafePerformIO). (Note that as Lyndon Maydwell pointed out, you cannot escape a monad using only Monad type class functions.) So it looks like in that sense you can get out of it. At this level, you can think of a monad like a function (which it often is, in fact). After you've applied a function to a value and got the result, you don't need the function any more. Ditto for a monad, except that for monads, the applying is usually done by a monad-specific runner function. Anton ___ Haskell-Cafe mailing list haskell-c...@haskell.orghttp://www.haskell.org/mailman/listinfo/haskell-cafe ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] Re: Can we come out of a monad?
So far the comments here only increase my confusion (which as I say, is not bad because it means that I am learning something!). As a Haskell newbie, the first thing I learned about monads is that they have a type signature that creates a kind of mud you can't wash off. eg. f :: String - MyMonad String By mentioning the monad, you get to use its special functions but as a hard price, you must return a value with a type signature that locks it within the monad (although you can remove the signature within other monads using -). As some people have hinted, perhaps the problem is that most Haskell newbies are introduced to monads through the IO monad and other monads are different. When I plunged into Haskell earlier this year, I had no problem with understanding static typing, higher level functions and even separating pure functions from IO functions. The more I learn about monads, however, the less I understand them. I've seen plenty of comments suggesting that monads are easy to understand, but for me they are not. Cheers, Kevin On Jul 30, 12:29 pm, Tillmann Rendel ren...@informatik.uni- marburg.de wrote: C K Kashyap wrote: I am of the understanding that once you into a monad, you cant get out of it? That's not correct. There are many monads, including Maybe, [], IO, ... All of these monads provide operations (=), return and fail, and do notation implemented in terms of these functions, as a common interface. Using just this common interface, you cannot get out of the monad. But most if not all monads also provide additional operations, specific to the monad in question. Often, these operations can be used to get out of that monad. For example, with Maybe, you can use pattern matching: case do x - return 5 fail some message return (x + 3) of Just a - a Nothing - 0 So we can get out of many monads, but we need to know which one it is to use the appropriate operation. Kevin Jardine wrote: I'm still trying to understand how monads interact with types so I am interested in this as well. From my point of view, the most important fact about monads is: There is nothing special about monads! The type class Monad behaves like very other type class. A monadic type constructor behaves like every other type constructor. The type class methods (=), return and fail behave like every other type class method. There is nothing special about monads. The only speciality of monads is do notation, but do notation is only a syntactic convenience, and can be translated into calls of (=), return and fail, which, as noted above, are not special in any way. So, back to your question, since there is nothing special about monads, monads do not interact with types in any special way. Tillmann ___ Haskell-Cafe mailing list haskell-c...@haskell.orghttp://www.haskell.org/mailman/listinfo/haskell-cafe ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] Re: Can we come out of a monad?
On Jul 30, 1:11 pm, Brent Yorgey byor...@seas.upenn.edu wrote: Monads are hard to understand. But they are *worth understanding*. That's the most inspiring and encouraging statement I've seen all week. Thanks! Kevin ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] Re: Lists and monads
Looks interesting. I've also come across Data.List.Class: http://hackage.haskell.org/packages/archive/generator/0.5.1/doc/html/Data-List-Class.html Has anyone used that? Kevin On Jul 27, 6:02 pm, wren ng thornton w...@freegeek.org wrote: Kevin Jardine wrote: But as I said, that is just an example. I keep wanting to apply the usual list tools but find that they do not work inside a monad. I find myself wishing that f (m [a]) just automatically returned m f([a]) Are you looking for these? import Data.Traversable as T T.sequence :: (T.Traversable t, Monad m) = t (m a) - m (t a) T.mapM :: (T.Traversable t, Monad m) = (a - m b) - t a - m (t b) -- N.B. T.mapM ~ (T.sequence . fmap) without me needing to do anything but I expect that there are reasons why that is not a good idea. Not all functors can be distributed over arbitrary monads, so not a good idea is more like not always possible or here be dragons (fluffy, intriguing, and pretty dragons to be sure; but probably deeper than the answer you were looking for). In addition to Applicative, the Traversable and Foldable classes should be key tools in your toolbox. They take a number of functions typically restricted to lists and generalize them to different functors, often with Applicatives or Monads involved. The Typeclassopedia should have more on them. -- Live well, ~wren ___ Haskell-Cafe mailing list haskell-c...@haskell.orghttp://www.haskell.org/mailman/listinfo/haskell-cafe ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] Lists and monads
As a Haskell neophyte, one of the things I find confusing is the way that the usual list functions (map, fold, ++, etc.) often cannot be used directly with monadic lists (m [a] or [m a]) but seem to require special purpose functions like ap, mapM etc. I get the idea of separating pure and impure code but am constantly frustrated by the fact that stuff that would be easy outside a monad seems to get more difficult inside, especially list manipulation. As a result I tend to write ugly recursive list functions that would be more appropriate with Python, say. I suspect that things are not quite as difficult as they appear, however, but cannot find any tutorials on monadic list manipulation. Any suggestions for resources in that area? Kevin ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] Re: Lists and monads
On Jul 26, 3:00 pm, Vo Minh Thu not...@gmail.com wrote: Also, just like with IO, maybe restructuring the code to separate monadic code would help. The specific monad I am dealing with carries state around inside it. I could revert to a pure system in many cases by simply passing the state as a parameter but then that defeats the point of the monad and clutters up my function calls. Also, in other cases, I am using a module that defines its own monads and have no choice but to use them. I think I would prefer a style of programming where monads are equal citizens to pure function calls. There are various hints that such a style of programming is possible but as I say, I have not found any clear tutorials on it. ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] Re: Lists and monads
On Jul 26, 3:19 pm, Vo Minh Thu not...@gmail.com wrote: Maybe you missed the part of my answer hinting to applicative style? No, I saw that but as I mentioned, I am looking for a tutorial. The source code alone means little to me. LYAH has a chapter about it[0]. Thanks for the pointer. I have read LYAH before (perhaps an earlier version) and did not notice that chapter. I'll take a look at it. Kevin ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] Re: Lists and monads
On Jul 26, 3:26 pm, Bill Atkins watk...@alum.rpi.edu wrote: Can you post an example of your code? Without getting into the complexities, one simple example is a fold where the step function returns results in a monad. I have taken to replacing the fold in that case with a recursive function, which surely is the wrong approach. I think foldM might do the job but am unsure. But as I said, that is just an example. I keep wanting to apply the usual list tools but find that they do not work inside a monad. I find myself wishing that f (m [a]) just automatically returned m f([a]) without me needing to do anything but I expect that there are reasons why that is not a good idea. Kevin ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] Re: Lists and monads
On Jul 26, 3:49 pm, Kevin Jardine kevinjard...@gmail.com wrote: I find myself wishing that f (m [a]) just automatically returned m f([a]) without me needing to do anything but I expect that there are reasons why that is not a good idea. Or is there a monadic list module where f(m [a]) = m f ([a]) ? It occurs to me that Haskell provides the tools to construct such a module (I think) so probably one exists? Kevin ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] Re: Lists and monads
On Jul 26, 4:12 pm, Bill Atkins watk...@alum.rpi.edu wrote: The answer is still applicative. :) OK, then I know where to spend my reading time. Thanks! Kevin ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] Re: Haskell Forum
Other topics I am interested in are served by both a web forum and a mailing list, usually with different content and participants in both. In my experience, routing one kind of content to another does not work very well because of issues of spam control, moderation, topic subdivisions, the ability to correct posts, and threading (usually web forums have these things and mailing lists do not). This works well in my view. Those people who prefer more structure and features post in the forum, those who prefer more traditional mailing lists post there, and anyone who wants to keep track of both streams subscribes to the RSS feeds. Personally I prefer web forums. Kevin On Jul 26, 5:03 pm, Magnus Therning mag...@therning.org wrote: On Mon, Jul 26, 2010 at 15:47, Nick Bowler nbow...@elliptictech.com wrote: On 10:37 Mon 26 Jul , Job Vranish wrote: I agree. A web forum would be more friendly to newcomers, easier to browse, and better organized, than the mailing list. I don't understand this sentiment at all. How are web forums easier to browse than list archives? Especially given that there are usually multiple archives for each ML, with a variety of ways to use them (e.g., I tend to use gmane with my newsreader for this purpose). Irrespective of what is easier to use, what really counts is where the *targets* of your post hang out. Personally I prefer a mailing list, and I would only ever use a forum if I had a better chance of getting good and informative answers there. Another option is to import the entire haskell-cafe archive into gmail :-) Some people will still prefer the mailing list of course, but I think there will be enough demand to justify a forum :) Wine has a web forum that is directly connected to their mailing lists: each post on the forum is sent to the corresponding list and vice versa. The web forum interface doesn't support proper threading, but it otherwise seems to work OK. Perhaps something like that would be useful? This would be a good compromise. /M -- Magnus Therning (OpenPGP: 0xAB4DFBA4) magnus@therning.org Jabber: magnus@therning.orghttp://therning.org/magnus identi.ca|twitter: magthe ___ Haskell-Cafe mailing list haskell-c...@haskell.orghttp://www.haskell.org/mailman/listinfo/haskell-cafe ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] Re: Haskell Forum
On Jul 26, 6:45 pm, Nick Bowler nbow...@elliptictech.com wrote: Since when do mailing lists not have threading? Web forums with proper support for threading seem to be few and far apart. Most of the email clients I'm familiar with don't support threaded displays and most of the web forums I'm familiar with do (although the feature is not always switched on). In my experience the debate between mailing list vs. web forum can become very emotional (especially when discussed via a mailing list) and I don't think it is that productive. Some people like one, some people like the other. That's why I think that it is useful to give people a choice. Kevin ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] Re: Haskell Forum
On Jul 26, 10:10 pm, Evan Laforge qdun...@gmail.com wrote: Interesting, I've never figured out why some people prefer forums, but you're proof that they exist :) This debate is eerily similar to several others I've seen (for example, on the interactive fiction mailing list). In every case I've seen, a web forum vs. mailing list debate has been pointless at best and sometimes turned into a flame war. I think that it's best for people who prefer a web forum to establish one and use it, and for those who prefer the mailing list approach to continue to use that. Cheers, Kevin ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] Re: Haskell Forum
On Jul 26, 10:37 pm, Nick Bowler nbow...@elliptictech.com wrote: It seems to me, then, that a wine-like web forum - mailing list gateway would satisfy everyone without fragmenting the community? Seehttp://forum.winehq.org/viewforum.php?f=2. -- Nick Bowler, Elliptic Technologies (http://www.elliptictech.com/) ___ Haskell-Cafe mailing list haskell-c...@haskell.orghttp://www.haskell.org/mailman/listinfo/haskell-cafe ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] Re: Haskell Forum
On Jul 26, 10:37 pm, Nick Bowler nbow...@elliptictech.com wrote: It seems to me, then, that a wine-like web forum - mailing list gateway would satisfy everyone without fragmenting the community? Definitely looks like an interesting option, although since Google groups and any decent web forum support RSS feeds, I'm not sure that having two different streams of content would fragment the community (any more than the many Haskell-related mailing lists do right now). Cheers, Kevin ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] Re: gd on Win32
Is there an easy way to install this module on Windows? I just ran cabal install gd and got the rather intimidating response: Missing C libraries: gd, png, z, jpeg, fontconfig, freetype, expat I actually have some of these libraries installed (eg. expat) but not most. I'm using MinGW. Cheers, Kevin On Jul 3, 12:27 am, Christopher Done chrisd...@googlemail.com wrote: OK, here's the cleaned up repo. ready for action: http://github.com/chrisdone/gd Uploaded to Hackage with me as maintainer:http://hackage.haskell.org/package/gd On 2 July 2010 21:34, Christopher Done chrisd...@googlemail.com wrote: On 2 July 2010 20:29, Matthew Gruen wikigraceno...@gmail.com wrote: I was wondering the same thing about submitting patches to expose more of the image functionality, including getting some functions to return Either instead of failing with a runtime error. Let me know when you get it set up. That sounds like a good idea. I've setup a repo, I've merged in the latest work I did on it, and I've just updated it to be latest Prelude/base and to comply with -Wall. I'm just going to make it consistent with tibbe's style guide[1] before we start patching it for feature updates, so that we're singing from the same hymn sheet and then I'll let you you here. The Github repo is here: http://github.com/chrisdone/gd What's your Github username? I will add you as a project admin so that you can push to it directly. [1]:http://github.com/tibbe/haskell-style-guide/blob/master/haskell-style.md ___ Haskell-Cafe mailing list haskell-c...@haskell.orghttp://www.haskell.org/mailman/listinfo/haskell-cafe ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] Re: gd on Win32
On Jul 21, 10:57 pm, Stephen Tetley stephen.tet...@gmail.com wrote: Given the number of libraries involved, I'd look for an alternative to GD. ___ Yes, I've seen reports that people have tried and failed to install the Haskell GD module on Windows. So I'm looking at something simpler now like shelling out to an imagemagick executable. Kevin ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] Haskell Platform dependency hell
I have Haskell Platform 2010.1.0.0 installed under Windows and I often find that Haskell breaks if I try upgrading some of the current modules. For example, after using cabal to upgrade to the latest version of Network.CGI, I can no longer compile any code and instead get this message: cabal.exe: dependencies conflict: ghc-6.12.1 requires array ==0.3.0.1 however array-0.3.0.1 was excluded because ghc-6.12.1 requires array ==0.3.0.0 The only way I have found to fix this problem in the past has been to uninstall the Haskell Platform and start over. Can anyone tell me: a. why does this occur, and b. what can I do to stop it from occurring again? Is it the case that the Haskell Platform is simply not upgradable and that I need to wait for the next release? Kevin ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] Heist template splice functions and custom monad
I'd like to run Heist template splice functions in my own custom monad. I can define a splice function as: mySplice :: Splice MyMonad However, when I try to call functions that return values in my monad in mySplice, I get a compile error: Couldn't match expected type TemplateMonad MyMonad a against inferred type MyMonad () I've seen an example in the Heist documentation where the inner MyMonad is accessed using lift. But when I try that, I get another compile error: No instance for (Monad Trans TemplateMonad) arising from the use of 'lift' What do I do to get this to work? Kevin ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] Efficient string construction
(I've done a basic Google search on this with no results. Apologies if this has been asked before.) I am coding a web application in which the content is a Unicode string built up over multiple functions and maintained in a State structure. I gather that the String module is inefficient and that Data.Text would be a better choice. Is it more efficient to build up a list of Text objects over time and combine them together with a single Data.Text.concat for the final output or to run Data.Text.append for each new string so that I am maintaining a single Text object rather than a list? As Data.Text.append requires copying both strings each time, my gut feeling is that concat would be much more efficient, but Haskell has surprised me before, so I wanted to check. Kevin ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Efficient string construction
--- On Thu, 6/3/10, Daniel Fischer daniel.is.fisc...@web.de wrote: Perhaps Data.ByteString[.Lazy].UTF8 is an even better choice than Data.Text (depends on what you do). I thought that I had the differences between the three libraries figured out but I guess not now from what you say. I had thought that String was a simple but memory inefficient model, that Text was for, well text, and that bytestrings were for binary data (eg. images, audio files and applications that required a true view on each text byte). So why is there a UTF8 implementation for bytestrings? Does that not duplicate what Text is trying to do? If so, why the duplication? When is each library more appropriate? Kevin ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] GPL answers from the SFLC (WAS: Re: ANN: hakyll-0.1)
I'm a Haskell newbie but long time open source developer and I've been following this thread with some interest. The GPL is not just a license - it is a form of social engineering and social contract. The idea if I use the GPL is that I am releasing free and open source software to the community. You are welcome to use it for any purpose but in exchange you must also agree to release any software you create that uses my software as free and open source. That is the difference between GPL and BSD type licenses. The GPL very deliberately creates an obligation. Yes, that can be inconvenient. It is meant to be inconvenient. Actually the GPL reminds me of a Haskell concept that I am struggling with right now - the monad. When I started writing Haskell code I was always trying to mix pure and IO code and I soon learned that once I used the IO monad I was stuck within it. The monad creates an inconvenient obligation and any IO code can only be used within other IO code. There are good reasons for monads (just as, in my view, there are good reasons for the GPL) but using them means that I need to make a lot of changes to the way I write software. Kevin ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] FastCGI under Windows
Just to provide completion to this thread, I gave up on Haskell Windows web development after discovering that some important libraries like network-minihttp did not compile under Windows (and I could never get FastCGI to work properly either, although it did compile). I'm now developing using Fedora running in VirtualBox. It took several hours to get the Haskell Platform installed properly under the Fedora version I'll be deploying to (Fedora 9), but now everything seems fine, including FastCGI. Since my end goal is to deploy to Fedora 9 in any case, this seems a good solution. Kevin --- On Thu, 11/26/09, Michael Snoyman mich...@snoyman.com wrote: From: Michael Snoyman mich...@snoyman.com Subject: Re: [Haskell-cafe] FastCGI under Windows To: Kevin Jardine kevinjard...@yahoo.com Cc: haskell-cafe@haskell.org Date: Thursday, November 26, 2009, 12:36 PM You could try calling the program as CGI instead of FastCGI to try and pin down where the error is coming from. Also, you could run a FastCGI script in a different language (Perl?) and see if that works. I can't say, however, that I've even used FastCGI on Windows. Michael On Thu, Nov 26, 2009 at 9:55 AM, Kevin Jardine kevinjard...@yahoo.com wrote: Just to add more detail: I am running Apache 2.2.9. The message I mentioned appeared in the Apache error log file when running the sample Haskell FastCGI scripts under localhost with mod_fastcgi. I understand that there are some problems with mod_fastcgi and Apache 2.2.9, so I downloaded the Apache 2.2.9 version of mod_fcgid from here: http://www.apachelounge.com/download/ and tried that instead. I no longer get the error message I mentioned before, but instead get: [Thu Nov 26 08:44:30 2009] [warn] mod_fcgid: read timeout from pipe [Thu Nov 26 08:44:30 2009] [error] [client 127.0.0.1] Premature end of script headers: test2.fcgi Any suggestions? Kevin --- On Wed, 11/25/09, Kevin Jardine kevinjard...@yahoo.com wrote: From: Kevin Jardine kevinjard...@yahoo.com Subject: [Haskell-cafe] FastCGI under Windows To: haskell-cafe@haskell.org Date: Wednesday, November 25, 2009, 10:44 PM I'm attempting to get FastCGI working with Haskell under Windows XP. However, all the sample code I've tried always fails with: user error (FCGX_Accept_r failed with error code: -) unknown listenType (0) Has anyone seen this before? Any ideas on what I could try to get this to work? Kevin ___ 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] FastCGI under Windows
Just to add more detail: I am running Apache 2.2.9. The message I mentioned appeared in the Apache error log file when running the sample Haskell FastCGI scripts under localhost with mod_fastcgi. I understand that there are some problems with mod_fastcgi and Apache 2.2.9, so I downloaded the Apache 2.2.9 version of mod_fcgid from here: http://www.apachelounge.com/download/ and tried that instead. I no longer get the error message I mentioned before, but instead get: [Thu Nov 26 08:44:30 2009] [warn] mod_fcgid: read timeout from pipe [Thu Nov 26 08:44:30 2009] [error] [client 127.0.0.1] Premature end of script headers: test2.fcgi Any suggestions? Kevin --- On Wed, 11/25/09, Kevin Jardine kevinjard...@yahoo.com wrote: From: Kevin Jardine kevinjard...@yahoo.com Subject: [Haskell-cafe] FastCGI under Windows To: haskell-cafe@haskell.org Date: Wednesday, November 25, 2009, 10:44 PM I'm attempting to get FastCGI working with Haskell under Windows XP. However, all the sample code I've tried always fails with: user error (FCGX_Accept_r failed with error code: -) unknown listenType (0) Has anyone seen this before? Any ideas on what I could try to get this to work? Kevin ___ 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