Re: [Haskell-cafe] GHC magic optimization ?
2009/12/4 Evan Laforge qdun...@gmail.com: The interesting thing is CAFs, which at the top level will never be out of scope and hence live forever. Untrue! CAFs can be garbage collected as well. See: http://www.haskell.org/pipermail/glasgow-haskell-users/2005-September/009051.html ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Are all arrows functors?
See also the paper Idioms are oblivious, arrows are meticulous, monads are promiscuous [1]. Functors can be extended to give applicative functors (idioms) which can then be extended to arrows, and then monads. So all arrows are also (applicative) functors. [1]: http://homepages.inf.ed.ac.uk/wadler/papers/arrows-and-idioms/arrows-and-idioms.pdf ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] What's this pattern called?
Conor also calls these functors: http://strictlypositive.org/slicing-jpgs/ The fixpoint construction builds recursive types (think trees) from functors by identifying superstructures with substructures: each node frames its children. ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] What *is* a DSL?
I'd also like to note that the canonical pronunciation of DSL ends in -izzle. ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] Re: A thought about liberating Haskell's syntax
Just occurred to me that you can actually do this with a preprocessor. If we extract the template declarations to a separate module, then it can happen something like this (I have corrected some errors in the above code): main.hs import Language.Haskell.TH import QList import Control.Monad {- pretend we had this: main = do print (1,2,3) print (1) print (1,(2,3)) print ((1,2),3) - template_outfix_lparen_rparen_expression matches normal parens in the expression context - we also have a template operator for commas The rules for the preprocessor are: inputs to the templates are always wrapped in [| |]. The templates are wrapped in $(). This explains some of the extraneous nesting below (trying to pretend I'm a machine!) -} main = do print $( template_outfix_lparen_rparen_expression `fmap` [| $( comma `fmap` [| 1 |] `ap` (comma `fmap` [| 2 |] `ap` [| 3 |]) ) |]) print $( template_outfix_lparen_rparen_expression `fmap` [| $( [| 1 |] ) |]) print $( template_outfix_lparen_rparen_expression `fmap` [| $( comma `fmap` [| 1 |] `ap` [| $(template_outfix_lparen_rparen_expression `fmap` [| $( comma `fmap` [| 2 |] `ap` [| 3 |]) |] ) |] ) |]) print $( template_outfix_lparen_rparen_expression `fmap` [| $( comma `fmap` [| $( template_outfix_lparen_rparen_expression `fmap` [| $(comma `fmap` [| 1 |] `ap` [| 2 |]) |] ) |] `ap` [| 3 |] ) |]) -- QList.hs --- {- contains the templates and QList. (the module created by preprocessor would usually only include templates, with QList being a helper module) -} module QList where import Debug.Trace import Language.Haskell.TH data QList a = QCons a (QList a) | QNil comma :: Exp → Exp → Exp a `comma` b@(AppE (AppE (ConE x) _) _) | x == qconsName = a `qcons` b | otherwise = a `qcons` (b `qcons` qnil) a `comma` b = a `qcons` (b `qcons` qnil) qnil :: Exp qnil = ConE (mkName QNil) qcons :: Exp → Exp → Exp a `qcons` b = (ConE (mkName QCons)) `AppE` a `AppE` b template_outfix_lparen_rparen_expression :: Exp → Exp template_outfix_lparen_rparen_expression x = case x of (AppE (AppE (ConE y) _) _) → if y == qconsName then TupE $ fromQList x else x _ → x fromQList :: Exp → [Exp] fromQList (AppE (AppE (ConE c) h) t) | c == qconsName = h:fromQList t | otherwise = error malformed qlist (head) fromQList (ConE n) | n == mkName QNil = [] | otherwise = error malformed qlist (tail) qconsName = mkName QCons ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] Re: A thought about liberating Haskell's syntax
Oh, and output is as expected: ./test (1,2,3) 1 (1,(2,3)) ((1,2),3) ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] Re: A thought about liberating Haskell's syntax
Also (sorry for the triple-post!) I noticed that in the TH documentation, it says: Type splices are not implemented, and neither are pattern splices This means, while we could write a preprocessor that would give us, e.g.: x :: Set Int x = {1,2,3,4} We cannot splice in the right places to allow: x :: {Int} x = {1,2,3,4} isSetEmpty :: {a} → Bool isSetEmpty {} = True isSetEmpty _ = False ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] A thought about liberating Haskell's syntax
Dear all, Here is a note concerning a thought I just had. I have written a rough sketch/outline and would like feedback upon this. The beginning thought: I would like to be able to write new bracket-like operators without having to rewrite GHC. (Case in point: applicative brackets.) First idea is to make them Template Haskell so we can mess with the internals (write custom list/set comprehension implementations). However a type (String → Exp) is not good enough; parsing the String is too much work! (Think precedence, etc.) We want to be able to have something (Exp → Exp). For this, we probably also need Template Haskell versions of normal (infix) operators, so that we can have something like: template infixr , (-1) -- lower precedence than $ a, b = if isList b then a : b else a : [b] Problem with this; [x, [y,z]] would have type :: [α] Lists constructed with ',' should have a different type from normal lists; call it QList. , :: Exp → Exp → Exp a, b@(AppE (ConE 'QCons) _) = a `qcons` b a, b = a `qcons` (b `qcons` QNil) where qcons a b = (ConE 'QCons) `AppE` a `AppE` b {- NB: we also need to provide implementations for type and pattern contexts, see next section. -} I believe that with this we can have the tuple and list syntax not hard-coded in. An example: -- note we need to provide the context for TH: Pattern, Expression, or Type -- no thought to sections here -- how to add tuple sections? -- perhaps relax operator rules for templates so that a, , , b is legitimate template outfix ( ) expression = (\x → case x of (QCons _ _) → TupE $ fromQList x _ → x template outfix ( ) pattern = (\x → case x of (QCons _ _) → TupP $ fromQList x _ → x template outfix ( ) type = (\x → case x of (QCons _ _) → foldl (\z x → z `AppT` x) (TupleT (length x)) x _ → x Anyway, we could then have easily-written syntax for; - sets - applicative brackets - parallel list comprehensions wouldn't have to be hardcoded (provide something like the above ',' but '|' returning something else. Perhaps QList should be tagged by a phantom type.) - statically-lengthed vectors Problems I can see: - QList (or other use-only-for-x types) could turn up in an actual program; l = a, b :: QList α -- is this actually a problem? - Hidden rewriting/macros not really the Template Haskell way, this is more scheme-like. A further (possibly evil) extension: template outfix do {-outdent-} expression = ... :) -- would require thinking about EOL handling/semi-colon insertion ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] How to calculate de number of digits of an integer? (was: Is logBase right?)
2009/8/26 Lennart Augustsson lennart.augusts...@gmail.com: Try 10^1000 Cheat :) ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] How to calculate de number of digits of an integer? (was: Is logBase right?)
You could also fudge the input: {-# LANGUAGE NoMonomorphismRestriction #-} log10 = floor . logBase 10 . (0.5+) . fromIntegral numDigits n | n 0 = 1 + numDigits (-n) numDigits 0 = 1 numDigits n = 1 + log10 n -- checked [0..10^8], finding a counter-example is left as an exercise :P ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Request for Changelogs
2009/8/7 Neil Mitchell ndmitch...@gmail.com: Which leaves me with the option of getting the darcs repo and looking through darcs changes. If I know of a repository for the package. I also don't tag the darcs version when I make a release - I probably should... This could be a nice feature for cabal (or an external tool... cabal-release?): auto-increment the version number (of course, the 'level' of release would have to be specified) and tag the current darcs repo accordingly, then 'cabal upload' it. - George ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] powerSet = filterM (const [True, False]) ... is this obfuscated haskell?
For each item, we ignore what the item actually is (hence `const`), and say that we both want it (True) and don't want it (False) in the output. Since we are using the list monad we are allowed to say this, and the filter function gives us a list of lists. I think there's probably a more intuitive name for `filterM`... ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Removing polymorphism from type classes (viz. Functor)
It does seem that having quantified contexts would make this *much* easier... ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] Removing polymorphism from type classes (viz. Functor)
Ok, so I have a small idea I'm trying to work on; call it a Prelude-rewrite if you want. For this I want to be able to have the hierarchy Functor → Applicative → Monad. For Functor, I would like to be able to implement it for a wider variety of types, as there are types which have aren't polymorphic which would also benefit from having an instance. My running example for this set of types is ByteString; the module contains the method: map ∷ (Word8 → Word8) → ByteString → ByteString However, we cannot use this for Functor because ByteString isn't polymorphic. To get around this, I devised the following: Introduce a type family which represents ‘points’ inside the type: type family Point f ∷ ★ For ByteString we have: type instance Point ByteString = Word8 For a polymorphic example (lists) we have: type instance Point [a] = a Now Functor becomes: class SimpleFunctor f where fmap ∷ (Point f → Point f) → (f → f) However, this doesn't allow for the existence of functions with the type (a → b). I need to introduce another type into the class: class Functor f g where fmap ∷ (Point f → Point g) → (f → g) But having two types isn't very nice (for one thing we can't introduce a fundep because for lists as it fails one of the coverage conditions), so introduce another type family to represent types which can be produced by giving a free variable: type Subst f a ∷ ★ type Subst [a] b = [b] type Subst ByteString b = ByteString class Functor f where fmap ∷ (Point f → Point (Subst f a)) → (f → Subst f a) I'm not sure how much of a hack this is, or if there is a better way. It seems to be OK... Now I want to implement Applicative. It would make sense to have ‘return’ be split out into a separate class, because this can be restricted in a similar way to Functor: class Pointed f where return ∷ Point f → f instance Pointed [a] where return x = [x] instance Pointed ByteString where return = BS.singleton Now, I want to be able to restrict Applicative to things which have [Pointed f, and forall a b. Point f ~ (a → b)]. At the moment I can't figure this out because I believe it would require something like the ‘quantified contexts’ proposal: class (Pointed f, ∀ a b. Point f ~ (a → b)) ⇒ Applicative f where ... I could have something like: class (Pointed f, Point f ~ (a → b)) ⇒ Applicative f a b where apply ∷ f → Subst f a → Subst f b This is still not very nice, because it requires two more type variables in the class, and the non-type-families version is far more straightforward... in fact, it makes sense for the Applicative class to have a polymorphic type because it must be able to have ‘return’ applied to arbitrary functions (remember [fmap f xs ≡ return f `apply` xs]). So back to: class Applicative f where apply ∷ f (a → b) → f a → f b But then ‘return’ cannot be added via a superclass restriction to Pointed! I seem to have painted myself into a corner. Does anyone see a better way to go about this? Thanks, - George ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Re: Haskell Platform on Ubuntu
2009/7/7 Matthias Görgens matthias.goerg...@googlemail.com: Karmic (9.10) will have GHC 6.10.3, possibly 6.10.4. It currently spots 6.10.3, in the alpha release I run here. A major problem is that the libraries are still for 6.8.2, so you cannot install the required libs to install cabal. Grr. ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] following up on space leak
I believe there might be an elegant solution for this using the `Last` monoid ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Monoid wants a (++) equivalent
This discussion points to a wider issue: at some stage we should look at pulling all the nice new stuff into Haskell prelude. I'm looking at you, Data.Foldable,Traversable. Also, throw out `map`. ;) ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Monoid wants a (++) equivalent
2009/7/4 Jason Dusek jason.du...@gmail.com: 2009/07/03 George Pollard por...@porg.es: Also, throw out `map`. ;) What is the proper name for the operation on functions of a functor, anyway? The name `fmap` seems to driven by an analogy with `map`. This is getting a little off topic, but I don't believe it has a name. In category theory the name of the functor is used as an operation on the function, so that given the functor F, instead of writing `fmap f` you'd write `F(f)`. I think this is one area where Haskell wins notationally :) ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] ANNOUNCE: text and text-icu, fast and comprehensive Unicode support using stream fusion
On Fri, 2009-02-27 at 00:01 -0800, Bryan O'Sullivan wrote: text-icu 0.1 Augments text with comprehensive character set conversion support and normalization (and soon more), via bindings to the ICU library. http://hackage.haskell.org/cgi-bin/hackage-scripts/package/text-icu Excellent! I was just wishing for this two days ago :D signature.asc Description: This is a digitally signed message part ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] ANNOUNCE: text and text-icu, fast and comprehensive Unicode support using stream fusion
Unfortunately it doesn’t build for me. I have libicu-dev 3.8.1 installed. $ cabal install text-icu Resolving dependencies... 'text-icu-0.1' is cached. Configuring text-icu-0.1... Preprocessing library text-icu-0.1... Error.hsc: In function ‘main’: Error.hsc:229: error: ‘U_ARGUMENT_TYPE_MISMATCH’ undeclared (first use in this function) Error.hsc:229: error: (Each undeclared identifier is reported only once Error.hsc:229: error: for each function it appears in.) Error.hsc:230: error: ‘U_DUPLICATE_KEYWORD’ undeclared (first use in this function) Error.hsc:231: error: ‘U_UNDEFINED_KEYWORD’ undeclared (first use in this function) Error.hsc:232: error: ‘U_DEFAULT_KEYWORD_MISSING’ undeclared (first use in this function) Error.hsc:260: error: ‘U_REGEX_OCTAL_TOO_BIG’ undeclared (first use in this function) Error.hsc:261: error: ‘U_REGEX_INVALID_RANGE’ undeclared (first use in this function) Error.hsc:262: error: ‘U_REGEX_STACK_OVERFLOW’ undeclared (first use in this function) Error.hsc:263: error: ‘U_REGEX_TIME_OUT’ undeclared (first use in this function) Error.hsc:264: error: ‘U_REGEX_STOPPED_BY_CALLER’ undeclared (first use in this function) compiling dist/build/Data/Text/ICU/Error_hsc_make.c failed command was: /usr/bin/gcc -c -D__GLASGOW_HASKELL__=610 -I/usr/local/lib/ghc-6.10.1/bytestring-0.9.1.4/include -I/usr/local/lib/ghc-6.10.1/base-4.0.0.0/include -I/usr/local/lib/ghc-6.10.1/include -IPAPI_INCLUDE_DIR dist/build/Data/Text/ICU/Error_hsc_make.c -o dist/build/Data/Text/ICU/Error_hsc_make.o cabal: Error: some packages failed to install: text-icu-0.1 failed during the building phase. The exception was: exit: ExitFailure 1 signature.asc Description: This is a digitally signed message part ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] A foray into type-level programming, and getting stuck
Okay, so I've written a small library to generalize 'fst' and 'snd' to arbitrary tuples, but I'd like to extend it a bit. I'm using the type-level library to do the thinking :) Imports and defines first: {-# LANGUAGE UnicodeSyntax, MultiParamTypeClasses, FunctionalDependencies, FlexibleInstances, FlexibleContexts, UndecidableInstances, DeriveDataTypeable, OverlappingInstances, ScopedTypeVariables #-} import Prelude hiding ((-),Eq) import qualified Prelude as P import Data.TypeLevel.Num.Sets import Data.TypeLevel.Num.Reps import Data.TypeLevel.Num.Aliases import Data.TypeLevel.Bool import Data.TypeLevel.Num.Ops import Data.Typeable I start by requiring that if you can access element 'n', you should be able to access element 'n-1'. class (ImplementsPrev t n a) ⇒ Nthable t n a | t n → a where nth ∷ n → t → a class (Pos n) ⇒ ImplementsPrev t n a instance (Pred n n', Nthable t n' a') ⇒ ImplementsPrev t n a instance ImplementsPrev t D1 a So, this is a simple induction. Testing it with the nthable instances confirms that it works; removing either of the first two lines stops the code from compiling, hurrah! instance Nthable (a,b,c) D1 a where nth _ (a,_,_) = a instance Nthable (a,b,c) D2 b where nth _ (_,b,_) = b instance Nthable (a,b,c) D3 c where nth _ (_,_,c) = c Now, I have heard talk/suggestions of revamping tuples in Haskell to a more flexible system. Perhaps we would like to do it like this (modulo strictness annotations): data (Nat n) ⇒ Tuple n a b = Tuple a b deriving (Show,Read,Typeable,P.Eq,Ord) infixr 0 `comma` -- comma :: a - (b ~ c) - (a ~ (b ~ c)) -- to investigate comma ∷ (Succ n n') ⇒ a → Tuple n b c → Tuple n' a (Tuple n b c) x `comma` y = Tuple x y empty ∷ Tuple D0 () undefined empty = Tuple () undefined Thus, we can create, e.g. (1 `comma` 2 `comma` empty). Now, I'd like to be able to write Nthable instances, so I start with the base case: instance (n :=: D1) ⇒ Nthable (Tuple n a b) D1 a where nth _ (Tuple a _) = a This works well. However, I am really stuck on the instance for the inductive case. My first idea was this: instance (Pred x x', Nthable b x' r) ⇒ Nthable (Tuple n a b) x r where nth _ (Tuple _ b) = nth (undefined ∷ x') b But this doesn't work, muttering about IncoherentInstances and hidden datatypes from the type-level library. So, I turn to Haskell café for help :) signature.asc Description: This is a digitally signed message part ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] ANN: The Typeclassopedia, and request for feedback
On Mon, 2009-02-16 at 15:30 +0100, Fraser Wilson wrote: Super! Also, best definition of bottom I've yet seen -- ignoring _| _, which is a party pooper. Like good code, it's short, to the point, and obviously correct. This brings up something I've thought about: On page 8, it is said that Pointed doesn't need to be checked because the theorem comes for free, but the free theorems paper was based upon total functions only; does having _|_ affect the free theorem for Pointed? - George signature.asc Description: This is a digitally signed message part ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Help needed with apache config for hackage
On Fri, 2009-02-13 at 22:39 +1100, George Pollard wrote: RewriteRule ^packages/archive/[^/]+/[^/]+/(.+)$ - [env=pkgname:$1] This should actually be more constrained since (as I've just noticed) more than just packages are under this path :) Perhaps: RewriteRule ^packages/archive/[^/]+/[^/]+/([^/]+\\.tar\\.gz)$ - [env=pkgname:$1] signature.asc Description: This is a digitally signed message part ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Re: Overloading functions based on arguments?
On Fri, 2009-02-13 at 11:40 +0100, Daniel Kraft wrote: Colin Adams wrote: If you have two functions that do two different things, then they certainly OUGHT to have different names. Well, they do the same thing but for different arguments; it's like this: Table is a table of name-value pairs I want to substitute in a tree-like structure using: substitute :: Table - Tree - Tree For substituting a single name-value pair I want to define this utitlity routine so I don't have to construct a Table all the time in the user code: substitute :: String - Value - Tree - Tree You can write it like this: class Substitutable a where substitute :: a - Tree - Tree instance Substitutable Table where ... instance Substitutable (String, Value) where ... signature.asc Description: This is a digitally signed message part ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Help needed with apache config for hackage
On Fri, 2009-02-13 at 10:58 +, Duncan Coutts wrote: Hi folks, Does anyone have any experience with apache configuration, particularly mime types and handling browser quirks and would like to help us with an issue we have on hackage? http://hackage.haskell.org/trac/hackage/ticket/498 The problem is described in the ticket but basically IE6 gets confused by the Content-Type and Content-Encoding and ends up saving .tar.gz files with the wrong name .tar.tar. We need help working out how to configure apache to use a workaround and with testing that the solution actually works. Thanks! Duncan Currently the browser receives: HTTP/1.1 200 OK Date: Fri, 13 Feb 2009 11:15:22 GMT Server: Apache/2.2.3 (Debian) Last-Modified: Mon, 09 Feb 2009 07:55:57 GMT ETag: 38c010-46d-b361bd40 Accept-Ranges: bytes Content-Length: 1133 Content-Type: application/x-tar Content-Encoding: x-gzip You could try adding a Content-Disposition header to specify a file name: Content-Disposition: attachment; filename=APackage.tar.gz In Apache you can (apparently [1],[2]) do it like this: RewriteRule ^packages/archive/[^/]+/[^/]+/(.+)$ - [env=pkgname:$1] Header set Content-Disposition attachment; filename=\%{pkgname}e\ env=pkgname [1]: http://httpd.apache.org/docs/2.0/mod/core.html#files [2]: http://www.experts-exchange.com/Software/Server_Software/Web_Servers/Apache/Q_23054616.html - George signature.asc Description: This is a digitally signed message part ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Help needed with apache config for hackage
On Fri, 2009-02-13 at 12:19 +, Duncan Coutts wrote: Can we do that just for one user agent? I don't think we want to use non-standard stuff in general. Apparently Content-Disposition is not in the official HTTP spec, but IE is known to follow it. It's not in the HTTP spec, but it's about as official as something that isn't can be :) [1] I believe all web browsers in common use support it. (And it shouldn't cause any problems for those that don't, who will just ignore it.) - George [1]: http://www.ietf.org/rfc/rfc2183.txt signature.asc Description: This is a digitally signed message part ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Re: Looking for pointfree version
On Thu, 2009-02-12 at 11:08 +0100, Heinrich Apfelmus wrote: Benja Fallenstein wrote: Kim-Ee Yeoh wrote: On the same note, does anyone have ideas for the following snippet? Tried the pointfree package but the output was useless. pointwise op (x0,y0) (x1,y1) = (x0 `op` x1, y0 `op` y1) import Control.Monad.Reader -- for the (Monad (a -)) instance import Control.Bifunctor -- package category-extras dup = join (,) mapPair = uncurry bimap pointfree = (mapPair .) . mapPair . dup Or if you're not afraid of *some* points, and want to avoid the imports: dup x = (x,x) mapPair (f,g) (x,y) = (f x, g y) pointfree op = mapPair . mapPair (dup op) That what you're looking for? :-) The pairs are of course an applicative functor (*) = uncurry (***) -- from Control.Arrow pure x = (x,x) pointwise op x y = pure op * x * y Regards, apfelmus Concretely (this might do with a few laziness notations): import Control.Applicative data Pair a = a :*: a instance Functor Pair where f `fmap` (x :*: y) = f x :*: f y instance Applicative Pair where (f :*: g) * (x :*: y) = f x :*: f y pure x = x :*: x pointfree :: (a - b - c) - Pair a - Pair b - Pair c --pointfree o x y = pure o * x * y pointfree = ((*) .) . (*) . pure -- in the applicative paper notation: --pointfree o x y = [| o x y |] signature.asc Description: This is a digitally signed message part ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Type families not as useful over functions
Can you live with infixl |$| (|$|) :: [a - r] - a - [r] fs |$| x = map ($ x) fs and, instead of broadcast fs a b use fs |$| a |$| b ? map ($ x) fs = { Applicative Functors satisfy... } pure ($ x) * fs = { 'interchange' rule from Control.Applicative } fs * pure x Thus; fs |$| x === fs * pure x fs |$| x |$| y === fs * pure x * pure y - George signature.asc Description: This is a digitally signed message part ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Why does sleep not work?
On Wed, 2009-02-11 at 01:50 +0100, Manlio Perillo wrote: George Pollard ha scritto: [...] So, it seems nanosleep get interruped by a signal. This works: import System.Posix main = do putStrLn Waiting for 5 seconds. blockSignals $ addSignal sigVTALRM emptySignalSet sleep 5 putStrLn Done. So (see my earlier email) `sleep` is lying about what interrupts it :) - George A possibly better solution is: sleep' :: Int - IO Int sleep' n = do n' - sleep n if n' == 0 then return 0 else sleep' n' From the trace, I see that nanosleep is being called 17 times here. Another solution is to set RTS flag: ./bug_sleep +RTS -V0 -RTS What strange is that the timer is created in non threaded RTS, too, but sleep is interrupted only with the threaded RTS. This may be caused by an incorrect execution of a foreign function marked safe. I just realized that for some reason I thought that `sleep` reported the signal that interrupted it... contrary to the documentation... as such, several of my replies to this thread may read as non-sequiturs :P signature.asc Description: This is a digitally signed message part ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Why does sleep not work?
I can confirm this behaviour, on: Linux 2.6.27-11-generic #1 SMP i686 GNU/Linux Difference in the RTS between non-working and working: (RTS way, rts_thr) (RTS way, rts) - George signature.asc Description: This is a digitally signed message part ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Why does sleep not work?
On Tue, 2009-02-10 at 09:57 -0800, Corey O'Connor wrote: The POSIX sleep function is defined as: sleep() makes the current process sleep until seconds seconds have elapsed or a signal arrives which is not ignored. Sounds like a signal is arriving that is interrupting the sleep. -Corey O'Connor I tested this when testing the original code; sleep reports that the signal received is 5 (SIGTRAP). However, the following code does not work: import System.Posix main = do putStrLn Waiting for 5 seconds. print sigTRAP blockSignals $ addSignal sigTRAP emptySignalSet signal - sleep 5 print signal putStrLn Done. This, on the other (strange) hand, does: import System.Posix main = do putStrLn Waiting for 5 seconds. blockSignals fullSignalSet signal - sleep 5 print signal putStrLn Done. - George signature.asc Description: This is a digitally signed message part ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Why does sleep not work?
On Wed, 2009-02-11 at 00:05 +0100, Manlio Perillo wrote: John Ky ha scritto: Hi Haskell Cafe, I wrote very short program to sleep for 5 seconds compiled with the -threaded option in ghc on the Mac OS X 1.5. I am finding that using the sleep function doesn't sleep at all, whereas using threadDelay does: [...] main = do putStrLn Waiting for 5 seconds. sleep 5 -- doesn't sleep at all putStrLn Done. Anybody know what's happening? Here is a syscal trace, on Linux: http://hpaste.org/fastcgi/hpaste.fcgi/view?id=1332#a1332 The interesting part: write(1, Waiting for 5 seconds.\n..., 23) = 23 rt_sigprocmask(SIG_BLOCK, [CHLD], [], 8) = 0 rt_sigaction(SIGCHLD, NULL, {SIG_DFL}, 8) = 0 rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0 nanosleep({5, 0}, 0xbf85f5cc) = ? ERESTART_RESTARTBLOCK (To be restarted) --- SIGVTALRM (Virtual timer expired) @ 0 (0) --- sigreturn() = ? (mask now []) write(1, 5\n..., 2) = 2 So, it seems nanosleep get interruped by a signal. This works: import System.Posix main = do putStrLn Waiting for 5 seconds. blockSignals $ addSignal sigVTALRM emptySignalSet sleep 5 putStrLn Done. So (see my earlier email) `sleep` is lying about what interrupts it :) - George signature.asc Description: This is a digitally signed message part ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Why does sleep not work?
Also attached is a diff for strace between non-threaded and threaded. execve(./sleep, [./sleep], [/* 38 vars */]) = 0 execve(./sleep, [./sleep], [/* 38 vars */]) = 0 brk(0) = 0x83c2000 | brk(0) = 0x8ff access(/etc/ld.so.nohwcap, F_OK) = -1 ENOENT (No such access(/etc/ld.so.nohwcap, F_OK) = -1 ENOENT (No such mmap2(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONY | mmap2(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONY access(/etc/ld.so.preload, R_OK) = -1 ENOENT (No such access(/etc/ld.so.preload, R_OK) = -1 ENOENT (No such open(/etc/ld.so.cache, O_RDONLY) = 3 open(/etc/ld.so.cache, O_RDONLY) = 3 fstat64(3, {st_mode=S_IFREG|0644, st_size=68273, ...}) = 0 fstat64(3, {st_mode=S_IFREG|0644, st_size=68273, ...}) = 0 mmap2(NULL, 68273, PROT_READ, MAP_PRIVATE, 3, 0) = 0xb801b000 | mmap2(NULL, 68273, PROT_READ, MAP_PRIVATE, 3, 0) = 0xb7f8d000 close(3)= 0 close(3) = 0 access(/etc/ld.so.nohwcap, F_OK) = -1 ENOENT (No such access(/etc/ld.so.nohwcap, F_OK) = -1 ENOENT (No such open(/lib/tls/i686/cmov/libutil.so.1, O_RDONLY) = 3 open(/lib/tls/i686/cmov/libutil.so.1, O_RDONLY) = 3 read(3, \177ELF\1\1\1\0\0\0\0\0\0\0\0\0\3\0\3\0\1\0\0\0\340\ read(3, \177ELF\1\1\1\0\0\0\0\0\0\0\0\0\3\0\3\0\1\0\0\0\340\ fstat64(3, {st_mode=S_IFREG|0644, st_size=9688, ...}) = 0 fstat64(3, {st_mode=S_IFREG|0644, st_size=9688, ...}) = 0 mmap2(NULL, 12424, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYW | mmap2(NULL, 12424, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYW mmap2(0xb8019000, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP | mmap2(0xb7f8b000, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP close(3)= 0 close(3) = 0 access(/etc/ld.so.nohwcap, F_OK) = -1 ENOENT (No such access(/etc/ld.so.nohwcap, F_OK) = -1 ENOENT (No such open(/lib/tls/i686/cmov/libdl.so.2, O_RDONLY) = 3 open(/lib/tls/i686/cmov/libdl.so.2, O_RDONLY) = 3 read(3, \177ELF\1\1\1\0\0\0\0\0\0\0\0\0\3\0\3\0\1\0\0\0 \n\0 read(3, \177ELF\1\1\1\0\0\0\0\0\0\0\0\0\3\0\3\0\1\0\0\0 \n\0 fstat64(3, {st_mode=S_IFREG|0644, st_size=9676, ...}) = 0 fstat64(3, {st_mode=S_IFREG|0644, st_size=9676, ...}) = 0 mmap2(NULL, 12408, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYW | mmap2(NULL, 12408, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYW mmap2(0xb8015000, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP | mmap2(0xb7f87000, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP close(3)= 0 close(3) = 0 access(/etc/ld.so.nohwcap, F_OK) = -1 ENOENT (No such access(/etc/ld.so.nohwcap, F_OK) = -1 ENOENT (No such open(/lib/tls/i686/cmov/libm.so.6, O_RDONLY) = 3 open(/lib/tls/i686/cmov/libm.so.6, O_RDONLY) = 3 read(3, \177elf\1\1\1\0\0\0\0\0\0\0\0\0\3\0\3\0\1\0\...@4\0\ read(3, \177elf\1\1\1\0\0\0\0\0\0\0\0\0\3\0\3\0\1\0\...@4\0\ fstat64(3, {st_mode=S_IFREG|0644, st_size=149332, ...}) = 0 fstat64(3, {st_mode=S_IFREG|0644, st_size=149332, ...}) = 0 mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONY | mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONY mmap2(NULL, 151680, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENY | mmap2(NULL, 151680, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENY mmap2(0xb801, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP | mmap2(0xb7f82000, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP close(3)= 0 close(3) = 0 access(/etc/ld.so.nohwcap, F_OK) = -1 ENOENT (No such access(/etc/ld.so.nohwcap, F_OK) = -1 ENOENT (No such open(/usr/lib/libgmp.so.3, O_RDONLY) = 3 open(/usr/lib/libgmp.so.3, O_RDONLY) = 3 read(3, \177ELF\1\1\1\0\0\0\0\0\0\0\0\0\3\0\3\0\1\0\0\0\200\ read(3, \177ELF\1\1\1\0\0\0\0\0\0\0\0\0\3\0\3\0\1\0\0\0\200\ fstat64(3, {st_mode=S_IFREG|0644, st_size=284176, ...}) = 0 fstat64(3, {st_mode=S_IFREG|0644, st_size=284176, ...}) = 0 mmap2(NULL, 287052, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENY | mmap2(NULL, 287052, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENY mmap2(0xb7fea000, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP | mmap2(0xb7f5c000, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP close(3)= 0 close(3) = 0 access(/etc/ld.so.nohwcap, F_OK) = -1 ENOENT (No such access(/etc/ld.so.nohwcap, F_OK) = -1 ENOENT (No such open(/lib/tls/i686/cmov/librt.so.1, O_RDONLY) = 3 open(/lib/tls/i686/cmov/librt.so.1, O_RDONLY) = 3 read(3, \177ELF\1\1\1\0\0\0\0\0\0\0\0\0\3\0\3\0\1\0\0\0`\31\ read(3,
Re: [Haskell-cafe] lazy evaluation is not complete
On Tue, 2009-02-10 at 08:03 +0100, Thomas Davie wrote: On 10 Feb 2009, at 07:57, Max Rabkin wrote: On Mon, Feb 9, 2009 at 10:50 PM, Iavor Diatchki iavor.diatc...@gmail.com wrote: I 0 * _ = I 0 I x * I y = I (x * y) Note that (*) is now non-commutative (w.r.t. _|_). Of course, that's what we need here, but it means that the obviously correct transformation of just to improve slightly: I 0 |* _ = I 0 I x |* I y = I (x * y) _ *| I 0 = I 0 I x *| I y = I (x * y) I x * | y = (I x |* I y) `unamb` (I x *| I y) Now it is commutative :) Bob See `parCommute` from the 'lub' package :) signature.asc Description: This is a digitally signed message part ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Haddock Markup
On Fri, 2009-02-06 at 01:35 +0100, David Waern wrote: I received this question from Lennart Augustsson (via Simon M) and thought I'd send out an inquiry to the Haskell community in general (Lennart, I hope you don't mind): Lennart writes: We have some local patches for haddock that extends the blah syntax so you can put TeX formulae in the documentation. It looks like, ! LaTeX stuff here !, but I'd like to extend it so you can process the string with any command. Are you interested in folding this into the main branch? So the question is about extending the Haddock markup language. When modifying the language we should think about the tension between familiarity, presentation features (pictures, math, whatever) and visual portability across different mediums (HTML, ghci, IDE tooltips, etc). And here I should say that Haddock already supports pictures using the url syntax. IMHO, adding ! LaTeX ! for TeX math is fine, because: - math in documentation is often useful - if you're going to write math, you need a format, even when the medium is plain text as in ghci. - TeX formulae seem to be relatively widely used and understood. My comment isn't related to the wider implications of third-party hooks into Haddock, but just for the (La?)TeX stuff itself. I think that the TeX *language* is great for writing mathematics, but that we should be wary of blindly incorporating TeX *output* into Haddock. Most of Haddock's documentation is currently HTML-based, and if we add TeX mathematics in the usual way (i.e. embedding images) it is very ‘inaccessible content’ (no selection, scaling, and a myriad of other small niggles) compared to the rest of the HTML file. My thoughts would be to use the TeX engine itself for when generating high-quality PDF documentation, and have something else translate TeX to (e.g.) MathML for the HTML pages. There are various programs to do this (or it could be done in Haskell :D!) Thanks, - George signature.asc Description: This is a digitally signed message part ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Re: Monades - I've got it! (hopefully)
On Wed, 2008-12-24 at 12:05 +, Johannes Waldmann wrote: in F# they renamed Monad to Workflow, see e.g. Chapter 9 (p. 230) in the Expert F# book. http://www.expert-fsharp.com/default.aspx I don't think this is helpful, it only really works for state-like monads. Workflow doesn't make sense at all for [a], for example. - George signature.asc Description: This is a digitally signed message part ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Employment
On Fri, 2009-01-23 at 16:19 +1100, Toby Hutton wrote: On Fri, Jan 23, 2009 at 11:56 AM, Jonathan Cast jonathancc...@fastmail.fm wrote: Not really. My company *advertises* for Haskell developers, and then when they come in to interview, informs them that the code base is actually written in Perl. Works, too --- we have several Haskellers working here. If all you care about is the quality of the developers, and not their productivity once you've got them, you don't actually need to let them use Haskell after the interview is over... I saw this trick recently for a job advertised locally to me, in Melbourne. I was initially pretty excited that someone in this city was actually advertising for Haskell programmers, until I realised they needed to be good at Javascript and Perl so they could work on their web apps. Argh, I didn't bother applying. I think I saw the same advertisement; unfortunately it was on a joint Australasian website so I was in the wrong country anyway :) ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] mapM_ - Monoid.Monad.map
On Fri, 2009-01-23 at 21:30 +, Joachim Breitner wrote: Hi, Am Freitag, den 23.01.2009, 21:50 +0100 schrieb Henning Thielemann: However our recent Monoid discussion made me think about mapM_, sequence_, and friends. I think they could be useful for many monads if they would have the type: mapM_ :: (Monoid b) = (a - m b) - [a] - m b I expect that the Monoid instance of () would yield the same efficiency as todays mapM_ will it? This is based on a naive, not well-founded understanding of haskell evaluation, but looking at instance Monoid () where mempty= () _ `mappend` _ = () mconcat _ = () I’d assume that evaluating mapM_ (putStrLn) lotsOfLargeStrings with your proposed mapM_ will leave a thunk equivalent to () `mappend` () `mappend` () `mappend`... in memory until the mapM_ has completely finished, where each () is actually an unevalutated thunk that still has a reference to one of the elements in the lotsOfLargeStrings list. Perhaps this is why the Monoid instance for () in GHC's source has the comment should this be strict? :) signature.asc Description: PGP signature rcmAttmntahOV2C Description: micalg/pgp-sha1 ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] A pattern type signature cannot bind scoped type variables `t'
On Mon, 2009-01-12 at 20:24 -0200, rodrigo.bonifacio wrote: Hi all, I'm trying to build a library that has the following code: hasTypeOf (TermRep (dx,_,_)) (x::t) = ((fromDynamic dx)::Maybe t) Could you do something like this? Enforce the types with a signature: hasTypeOf :: (Typeable t) = Dynamic - t - Maybe t hasTypeOf x _ = fromDynamic x hasTypeOf (toDyn (2::Int)) (undefined::Integer) Nothing hasTypeOf (toDyn (2::Int)) (undefined::Int) Just 2 Or if you just want boolean result: hasTypeOf x y = typeOf y == dynTypeRep x rcmAttmntN3MDzg Description: micalg/pgp-sha1 ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] some ideas for Haskell', from Python
On Wed, 2009-01-14 at 15:59 +0100, Manlio Perillo wrote: 1) In a Python string it is available the \U{name} escape, where name is a character name in the Unicode database. As an example: foo = uabc\N{VULGAR FRACTION ONE HALF} This is possible via QuasiQuotation, you can write a parser that will let you do it like this: foo = [$s|abc\N{VULGAR FRACTION ONE HALF}|] I started to write one but got stuck :P By working from the wiki page [1] I ended up with some code that will let you do: let e = 3 in [$s|h\V{e}llo\U{32}world|] == h3llo world I got stuck on a few things: - how best to allow arbitrary expressions (requires additional parsing to allow braces inside strings and so on, e.g. [$s|hello \E{}} world|]) - can't figure out how to write the quoting function for the patterns... this would be awesome if it worked: everythingAfterFirstK [$s|\V{before}k\V{after}|] = after - there's no library for looking up characters by name. 'unicode-names' has getCharacterName but not the inverse. Code follows: StringSplicer.hs {-# LANGUAGE DeriveDataTypeable #-} module StringSplicer where import Data.Generics import Text.ParserCombinators.Parsec import Control.Monad data Exp = StringLit String | Unicode Int | Variable String | Backslash deriving (Show, Typeable, Data) interp = do char '\\' c - choice [char 'U', char 'V', char '\\'] case c of 'U' - do char '{' n - many1 digit char '}' return $ Unicode (read n) 'V' - do char '{' s - manyTill anyChar (try $ char '}') return $ Variable s '\\' - return Backslash str = do s - many1 $ noneOf ['\\'] return $ StringLit s expr = many $ interp | str parseString :: Monad m = (String, Int, Int) - String - m [Exp] parseString (file, line, col) s = case runParser p () s of Left err - fail $ show err Right e - return e where p = do pos - getPosition setPosition $ (flip setSourceName) file $ (flip setSourceLine) line $ (flip setSourceColumn) col $ pos e - expr eof return e StringSplicer.Quote.hs module StringSplicer.Quote where import Data.Generics import qualified Language.Haskell.TH as TH import Language.Haskell.TH.Quote import Data.Char (chr) import StringSplicer quoteExprExp :: String - TH.ExpQ quoteExprPat :: String - TH.PatQ s :: QuasiQuoter s = QuasiQuoter quoteExprExp quoteExprPat parseIt x = do loc - TH.location let pos = (TH.loc_filename loc, fst (TH.loc_start loc), snd (TH.loc_start loc)) parseString pos x quoteExprExp x = do expr - parseIt x it - dataToExpQ (const Nothing `extQ` antiExprExp) expr return $ TH.AppE (TH.VarE (TH.mkName concat)) it quoteExprPat x = do expr - parseIt x it - dataToPatQ (const Nothing `extQ` antiExprPat) expr error help! antiExprExp :: Exp - Maybe (TH.Q TH.Exp) antiExprExp (StringLit s) = Just $ TH.litE (TH.stringL s) antiExprExp (Backslash) = Just $ TH.litE (TH.stringL \\) antiExprExp (Unicode n) = Just $ TH.litE (TH.stringL [chr n]) antiExprExp (Variable v) = Just $ TH.appE (TH.varE (TH.mkName show)) (TH.varE (TH.mkName v)) antiExprPat :: Exp - Maybe (TH.Q TH.Pat) antiExprPat (Unicode n) = Just $ TH.litP (TH.stringL [chr n]) antiExprPat (Backslash) = Just $ TH.litP (TH.stringL \\) antiExprPat (StringLit s) = Just $ TH.litP (TH.stringL s) antiExprPat (Variable v) = Just $ TH.varP (TH.mkName v) [1]: http://haskell.org/haskellwiki/Quasiquotation signature.asc Description: This is a digitally signed message part ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Comments from OCaml Hacker Brian Hurt
On Thu, 2009-01-15 at 18:10 -0500, Cale Gibbard wrote: My personal preference would be: class Monoid m where zero :: m (++) :: m - m - m (in the Prelude of course) - Cale I've tried doing this (and making more widespread use of typeclassed operations) by writing my own AltPrelude. Unfortunately there is still a lot of 'unrebindable' syntax (list comprehensions, 'error' forced to exist in Monad, if-then-else not using nearest Bool, etc) which makes this hard to achieve. signature.asc Description: This is a digitally signed message part ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] unfoldr [ANN: HLint 1.2]
On Mon, 2009-01-12 at 21:48 +, Robin Green wrote: convert b = unfoldr (\n - if n 0 then Just (n `mod` b, n `div` b) else Nothing) I have the nice function 'toMaybe' which simplifies this to: unfoldr (\n - toMaybe (n0) (n `mod` b, n `div` b)) I would use the more general idiom: unfoldr (\n - guard (n 0) return (n `mod` b, n `div` b)) I have the equivalent in my ‘useful functions’: ifM p x = if p then return x else mzero signature.asc Description: This is a digitally signed message part ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Real World Haskell: confusion
On Tue, 2009-01-13 at 11:46 -0600, Derek Elkins wrote: No, it means exactly what you said it means. People abuse it to mean the second sense. Those people are wrong and there is already a term for that second sense, namely partial application. I really wish people would stop conflating these terms*, all it does is create confusion. To Eugene: The suggested meaning of curriable, namely able to be curried, does not make sense. curry takes an uncurried function to a curried form. * A related annoyance is people who talk about languages supporting currying and/or partial application. Unless one means that the language supports higher order functions at all by that, it doesn't make any sense. Haskell has no support for currying or partial application. The fact that most functions are in curried form in Haskell is merely a convention (with, admittedly strong -social- ramifications.) The only way one could say Haskell supports currying is that it has a lightweight notation for nested lambdas. I’d almost say that there is no such thing as partial application in Haskell. Since every: f ∷ a → b → c is really: f ∷ a → (b → c) there are no multiple arguments to be applied ‘partially’, only a function ‘f’ that takes one argument and gives you another, anonymous, function. - George signature.asc Description: This is a digitally signed message part ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Logos of Other Languages
On Fri, 2008-12-19 at 00:10 -0800, Ashley Yakeley wrote: I browsed around a bit for logos from other languages... ... All of these get one thing right that the current and most of the proposed Haskell logos do not: they don't make any reference to the syntax of the language itself. Doing so seems to miss the point of a logo: it's supposed to appeal visually, rather than semantically. So I'd like to see some submissions that don't use lambdas. I commented on this to Cale; ... the mountain is the only real 'iconic' one :), ruby has a ruby, python has pythons, java has its coffee, lua has the moon, Scheme had the lambda before Haskell, perl has its (de facto) camel, etc. C(++|#) and older languages tend to be the odd ones out This is why I like Cale's mountain (which incorporates a sneaky lambda ;P). A mountain peak/summit/apex also has nice connotations! http://haskell.org/haskellwiki/Haskell_logos/New_logo_ideas#Cale_Gibbard signature.asc Description: This is a digitally signed message part ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Detecting system endianness
On Thu, 2008-12-18 at 22:35 -0500, wren ng thornton wrote: In a similar vein, is there already a function available to give the size of Word in bytes? Or should I write the usual Ptr conversion tricks to figure it out? How about this: (`div` 8) $ ceiling $ logBase 2 $ fromIntegral (maxBound :: Word) Could write an integral log_2 function to make it nicer :) - George signature.asc Description: This is a digitally signed message part ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Re: Time for a new logo?
It has a military feeling I don't like... Might look cuddlier with slightly rounded edges. That's what all the cool kids[1] are doing anyway ;) [1]: http://www.python.org/ signature.asc Description: This is a digitally signed message part ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Re: Time for a new logo?
On Wed, 2008-12-17 at 21:46 +0100, Martijn van Steenbergen wrote: If you play with the angles and vary the stroke thicknesses you'll probably get a friendlier look, vs. the military/airline look these have now. The first '' doesn't have to be the same thickness as the lambda. If you look at fonts: characters in a font aren't all straight either; they bend a bit (so that is more than just round corners) and this makes them a lot more interesting. Various levels of bendiness yield various levels of playfulness. While I already like this logo a lot, I think it could be improved a lot more by making it more fonty. Note that I'm not saying it should be a very playful logo, just a more fonty one... yeah. Might be interesting to try angling the ends of the stems to look something more like the guillemot in [1]. I might try this in Gimp but I'm no designer :P [1] http://haskell.org/sitewiki/images/6/62/Haskell_logo_ideas_falconnl.png signature.asc Description: This is a digitally signed message part ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Re: Time for a new logo?
Might be interesting to try angling the ends of the stems to look something more like the guillemot in [1]. I might try this in Gimp but I'm no designer :P Here is what I got; I think I chose the wrong yellow :) Based it on the font Diavlo, which is free. attachment: hasklogo.png signature.asc Description: This is a digitally signed message part ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Time for a new logo?
On Tue, 2008-12-16 at 12:40 -0500, Darrin Thompson wrote: My $0.02 us: Apologies for ascii art, and hopefully gmail doesn't munge this: \\ \\ \\ \\ \| \\ \\ --- \\ \\ // / \ // / \ \| // / /\\ --- // / / \\ --- / / / \ / / / /\ \ / / --- / / / / / / \ \ \ \ \ \ --- \ \ \ \ \ \/ / \ \ \/ --- signature.asc Description: This is a digitally signed message part ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Re: Time for a new logo?
On Wed, 2008-12-17 at 02:47 +, Jeff Wheeler wrote: Darrin Thompson darrinth at gmail.com writes: My $0.02 us: Apologies for ascii art, and hopefully gmail doesn't munge this: I love this ASCII-art version. I tried to make a vector version of it in Photoshop, and I came up with this [1] and [2]. Any critiques/suggestions? I'm thinking about a second version that more obviously defines the second '' with color from the bottom-right part of the lambda. Jeff Wheeler [1]: http://media.nokrev.com/junk/haskell-logos/logo1.png [2]: http://media.nokrev.com/junk/haskell-logos/logo2.png I like the first version better. :) I'd suggest making the lambda/arrow a bit straighter and beefing up the size of the equals in relation to the rest of the symbol :) signature.asc Description: This is a digitally signed message part ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Data.List.Split
On Mon, 2008-12-15 at 08:40 +, Neil Mitchell wrote: That can only be a bug in stream fusion - concatMap should always be prefered! Yes, but it is unclear from the article whether the concatMap (w/ stream fusion enabled) is Data.List.Stream's concatMap or the Prelude's concatMap. It's only a bug in the former case :) - George signature.asc Description: This is a digitally signed message part ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Re: haskell compiler never comes back
So I retract that email ;) signature.asc Description: This is a digitally signed message part ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] Minimal complete definitions
Good afternoon Café, I've written a little bit of code to calculate minimal complete definitions for a class given which of its functions use which other functions. As an example: doDependencies ord = ([],[[=],[compare]]) doDependencies num = ([plus,times,abs,signum,fromInteger],[[minus],[negate]]) The first part of the pair is those functions which must *always* be implemented, the second part is a list of possible minimal complete definitions available for the provided list. This can help catch mistakes; a comment in the GHC source for GHC.Classes notes that compare must be implemented using (=) and not () in order to give the minimal complete definition (= OR compare). If we use the incorrect () then my code calculates the MCD as: doDependencies wrongOrd = ([],[[],[,=,compare],[compare]]) That is, the MCD is ( OR ( AND = AND compare) OR compare). Now I have two questions: 1) Is my code correct? ;) 2) Could this be incorporated into GHC in order to detect when someone hasn't provided a sufficient definition for a class? As an example, it could detect this: ~$ cat test2.hs data Die d = Die d instance Eq (Die d) where main = do let i = Die stack overflow print (i == i) ~$ ghc -Wall test2.hs --make ~$ ./test2 Stack space overflow: current size 8388608 bytes. Use `+RTS -Ksize' to increase it. Given the following: doDependencies [(==, Just [/=]),(/=, Just [==])] = ([],[[/=],[==]]) GHC could warn that either (==) or (/=) must be implemented. Thanks, - George signature.asc Description: This is a digitally signed message part ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Minimal complete definitions
Code might help :P import qualified Data.Set as Set import Data.Set (Set) import Data.List (partition,delete) import Data.Maybe (isJust,fromJust) -- A snippet for working out minimal complete definitions. num = [ (plus,Nothing), (times,Nothing), (abs,Nothing), (minus,Just [negate]), (negate,Just [minus]), (signum,Nothing), (fromInteger,Nothing) ] ord = [ (compare,Just [=]), (,Just [compare]), (=,Just [compare]), (,Just [compare]), (=,Just [compare]), (max,Just [=]), (min,Just [=]) ] -- a nice example from a comment in GHC's GHC.Classes wrongOrd = [ (compare,Just []), (,Just [compare]), (=,Just [compare]), (,Just [compare]), (=,Just [compare]), (max,Just [=]), (min,Just [=]) ] -- given a list of: -- (thing, depends upon) -- * depends upon can be Nothing if no implementation is defined (i.e. -- you *always* have to implement it -- * depends upon can be Just [] if the implementation depends on nothing else -- * otherwise the depends upon is Just [a] where it lists the things it depends upon -- -- returns: -- (a list of what you must always implement, and lists of minimal dependencies) -- doDependencies :: [(a, Maybe [a])] - (a,[[a]]) doDependencies xs = (mustImplementNames,Set.toList . Set.fromList $ map (Set.toList . Set.fromList) $ doDependencies' maybeImplement'') where (maybeImplement,mustImplement) = partition (isJust . snd) xs mustImplementNames = map fst mustImplement maybeImplement' = map (\(x,y)-(x,fromJust y)) maybeImplement maybeImplement'' = foldr eliminateDepends maybeImplement' mustImplementNames eliminateDepends :: (Ord a, Eq a) = a - [(a,[a])] - [(a,[a])] eliminateDepends x xs | null removeUs = stillHere | otherwise = foldr eliminateDepends stillHere (map fst removeUs) where (removeUs,stillHere) = partition (null . snd) $ map (\(it,depends) - (it, delete x depends)) xs doDependencies' :: (Ord a, Eq a) = [(a,[a])] - [[a]] doDependencies' eqs = dd eqs [] where dd [] solution = [solution] dd eqs solution = [concat $ dd (eliminateDepends dependency eqs) (dependency:solution) |dependency-rhs] where rhs = concatMap snd eqs signature.asc Description: This is a digitally signed message part ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Minimal complete definitions
Sorry about the triple-post, but I forgot to note it only goes to one 'depth' of OR; in reality the MCD for wrongOrd should be ( OR ((=) AND (compare OR )) OR compare). This requires a slightly more complicated type than [[a]] :) signature.asc Description: This is a digitally signed message part ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Time for a new logo?
? attachment: cover.jpg signature.asc Description: This is a digitally signed message part ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Data.List.Split
On Sun, 2008-12-14 at 00:35 -0500, Adam Vogt wrote: On another note, is there much use of such simple library functions: does concatMap, for instance, save anything other than a couple parantheses, or does (concat . map) not necessarily get optimized into the same thing Bart Massey’s results suggest very little difference: http://wiki.cs.pdx.edu/forge/concatmap.html (Yellow blobs + green crosses.) - George signature.asc Description: This is a digitally signed message part ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Data.List.Split
On Sun, 2008-12-14 at 19:46 +1300, George Pollard wrote: On Sun, 2008-12-14 at 00:35 -0500, Adam Vogt wrote: On another note, is there much use of such simple library functions: does concatMap, for instance, save anything other than a couple parantheses, or does (concat . map) not necessarily get optimized into the same thing Bart Massey’s results suggest very little difference: http://wiki.cs.pdx.edu/forge/concatmap.html (Yellow blobs + green crosses.) I should have said that, on the other hand, with stream fusion enabled, (concat . map) outperforms (concatMap) :) - George signature.asc Description: This is a digitally signed message part ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] Numerics implementing different instances of the same class
Is there a good way of doing this? My running example is Monoid: class Monoid a where operation :: a - a - a identity :: a With the obvious examples on Num: instance (Num a) = Monoid a where operation = (+) identity = 1 instance (Num a) = Monoid a where operation = (*) identity = 0 Of course, this won't work. I could introduce a newtype wrapper: newtype (Num a) = MulNum a = MulNum a newtype (Num a) = AddNum a = AddNum a instance (Num a) = Monoid (MulNum a) where operation (MulNum x) (MulNum y) = MulNum (x * y) identity = MulNum 1 instance (Num a) = Monoid (AddNum a) where ... -- etc However, when it comes to defining (e.g.) a Field class you have two Abelian groups over the same type, which won't work straight off: class Field a where ... instance (AbelianGroup a, AbelianGroup a) = Field a where ... Could try using the newtypes again: instance (AbelianGroup (x a), AbelianGroup (y a) = Field a where ... ... but this requires undecidable instances. I'm not even sure if it will do what I want. (For one thing it would also require an indication of which group distributes over the other, and this may restore decidability.) I'm beginning to think that the best way to do things would be to drop the newtype wrappers and include instead an additional parameter of a type-level Nat to allow multiple definitions per type. Is this a good way to do things? Has anyone else done something similar? I've taken a look at the Numeric Prelude but it seems to be doing things a bit differently. (e.g. there aren't constraints on Ring that require Monoid, etc) - George signature.asc Description: This is a digitally signed message part ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] Origins of '$'
Hello Haskell-Café: This is a little bit random, but I was just wondering if anyone knew where the $ low-precedence parenthesis-eliminating application operator originated. The Haskell Report doesn't mention anything, and I can't search for $ on Google. So... who thought it up? Does it originate in an earlier language, or is it uniquely Haskellish? :) - George signature.asc Description: This is a digitally signed message part ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Re: Why 'round' does not just round numbers ?
There's also the ieee-utils package, which provides an IEEE monad with `setRound`: http://hackage.haskell.org/packages/archive/ieee-utils/0.4.0/doc/html/Numeric-IEEE-RoundMode.html signature.asc Description: This is a digitally signed message part ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Rewrite rules
On Thu, 2008-10-16 at 09:01 +0100, Ryan Ingram wrote: Isn't this an unsound rewrite? Yeah, hence the just for fun :) Anyways, the reason for inlining not being done if an expression is used more than once is that it duplicates work that you explicitly specified should only be done once (by placing it in a let). Okay, thanks :) signature.asc Description: This is a digitally signed message part ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Flexible instances
Thanks to all that replied (Derek Ryan for the major understanding, Albert Luke also)*. I guess I was getting confused with the error message: (All instance types must be of the form (T a1 ... an) I was interpreting this with Stringable/Enum as T and [Char]/Blah as a1. Now I have clarity! I shall have to follow up Iavor's lead on why this *is*. Thanks! *[Silly email reply system; discussions on the internet should form an acyclic directed graph, not a tree! This, incidentally, is why I'm replying to myself.] signature.asc Description: This is a digitally signed message part ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] Rewrite rules
Section 8.13.2 of the GHC manual[1] states: GHC keeps trying to apply the rules as it optimises the program. For example, consider: let s = map f t = map g in s (t xs) The expression s (t xs) does not match the rule map/map, but GHC will substitute for s and t, giving an expression which does match. If s or t was (a) used more than once, and (b) large or a redex, then it would not be substituted, and the rule would not fire. The part I'm interested in here is (a); if an expression is used more than one then it cannot be substituted for. Is there any way to work around this or force it? The reason I ask is that as a bit of fun (and inspired by Joachim Breitner's blog post [2]) I was going to try writing a rewrite rule for the first time. What I had in mind was this: {-# RULES index cycled list forall list n. cycle list !! n = list !! (n `mod` length list) #-} However, in the case he has written about this won't fire, since the LHS cannot be substituted as `cycle list` is used more than once: let rlist = cycle list print ( rlist !! (10^9), rlist !! 0 ) I can get it to fire again if I write it like this: {-# RULES !!/cycle forall list. (!!) (cycle list) = (\n - list !! (n `mod` length list)) #-} ... let rlist = (!!) (cycle list) print (rlist (10^9), rlist 0) But this is non-obvious and I'd rather have it fire in the first case (i.e. when used naïvely). So, back to my question; is there a workaround or force for this... or does it break too many things if done? [1] http://www.haskell.org/ghc/docs/latest/html/users_guide/rewrite-rules.html#id414792 [2] http://www.joachim-breitner.de/blog/archives/308-guid.html signature.asc Description: This is a digitally signed message part ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] OT: Haskell desktop wallpaper?
Needs text in Haskell's official font ;) http://research.microsoft.com/~simonpj/papers/haskell-tutorial/TasteOfHaskell.pdf http://research.microsoft.com/~simonpj/papers/ndp/NdpSlides.pdf http://research.microsoft.com/~simonpj/papers/marktoberdorf/Marktoberdorf.ppt signature.asc Description: This is a digitally signed message part ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] newbie questions (read, etc., with Data.ByteString.Lazy.Char8)
On Mon, 2008-10-06 at 21:06 -0500, Mike Coleman wrote: There's a readInt method, which I guess I could use, but it returns a Maybe, and I don't see how I can easily strip that off. You can use Data.Maybe's 'mapMaybe' function The mapMaybe function is a version of map which can throw out elements. In particular, the functional argument returns something of type Maybe b. If this is Nothing, no element is added on to the result list. If it just Just b, then b is included in the result list. So we change this: -- lazy version (doesn't compile) -- file: ch08/SumFile.hs import qualified Data.ByteString.Lazy.Char8 as L main = do contents - L.getContents print (sumFile contents) where sumFile = sum . map read . L.words To this: import qualified Data.ByteString.Lazy.Char8 as B import Data.Maybe (mapMaybe) main = do contents - B.getContents print (sumFile contents) where sumFile = sum . map fst . mapMaybe B.readInt . B.words Now, there is a problem with this; the original version will not read integers that are followed by garbage, whereas this one will. The difference is between readInt and read: (read 2a) will fail, (readInt 2a) will return Just (2,a) readInt is really designed with parsers in mind. So, we need to filter out anything readInt returns with a non-empty string in the right part of the tuple. Ending up with this: sumFile = sum . map fst . filter (B.null . snd) . mapMaybe B.readInt . B.words Actually, after saying this, the original version probably just dies when given garbage :P signature.asc Description: This is a digitally signed message part ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] Restricted file reading monad
Hello all, I'm currently working on a (toy) ID3 [1] tag reader, which made me think of a library which might be quite useful. The structure of an ID3 tag goes something like this: Header: - total size of tag - other header info A series of frames, each with: - total size of frame - other header info - frame data Since the ID3 tag as a whole has size information, I need to pass that into the frame-reading functions to ensure that I never read past the end of the total header. This exact same requirement is present within the frame-reading function itself; it must read the frame data without reading past the end of the frame. It would be nice to have some kind of monad or similar so that I could do: readTag = do size - -- read size -- read other header info withLimit size $ -- read frames then the read-frames function would be able to do its work without having to worry about size-checking all the time, as this would be implicit. (And similarly with the frame-reading functions as well.) This could easily be extended to: f x = readManyWithLimit size readerFunction where readManyWithLimit would return a list of results of applying the reader function as many times as possible within the size limit (and possibly returning some kind of error if the reader function 'bails early' and doesn't gobble right up to the end of the size limit). The thing is, I've not implemented a monad of any substantial size so I don't have a clue where to start. Calling it FileReader (for want of a better name), I guess it would almost be the same as a parsing monad, so the type would have a reference to the file Handle and the current index into the file, as well as the last point that it's allowed to read up to. So, umm... a rather open-ended question, but how would I go about this? [1]: http://www.id3.org/Developer_Information signature.asc Description: This is a digitally signed message part ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] Parsing indentation-based languages with Parsec
Hi, first time list poster :) I've searched around a bit but haven't been able to find any examples of this. I want to be able to parse a language (such as Haskell, Python) which has only EOL as the 'statement' separator and has indentation levels to indicate block structure. Whilst doing this I want to use Parsec's nice library. The first thing I noticed was that Parsec's whiteSpace parser will ignore EOL as just whiteSpace, so I need to redefine that. Is this the correct way to do it? I've only been using Haskell for a week or so so I'm not too sure on the record structures and updating them... lexer :: P.TokenParser () lexer = ( P.makeTokenParser emptyDef { commentLine= #, nestedComments = True, identStart = letter, identLetter= letter, opStart= oneOf +*/-=, opLetter = oneOf +*/-=, reservedNames = [], reservedOpNames = [], caseSensitive = False } ) { --update lexer fields P.whiteSpace = do --just gobble spaces many (char ' ') return () } (I got the basic code from the tutorial contained within the Parsec docs.) For handling the indented blocks I thought I would use something to hold current indentation state, as Parsec has support for threading state through all the parsers. Is this the right way to go about this? Has anyone done the 'groundwork' with parsing such languages so I don't need to reinvent this? Thanks in advance, - porges. signature.asc Description: This is a digitally signed message part ___ Haskell-Cafe mailing list [EMAIL PROTECTED] http://www.haskell.org/mailman/listinfo/haskell-cafe