[Haskell-cafe] Re: Haskell good for parallelism/concurrency on manycore?
Ahn == Ahn, Ki Yung kya...@gmail.com writes: Ahn P.S. If you happen to be a local Korean expert on this matter, Ahn sorry for my ignorance, and I'd be happy to forward their inquiry Ahn to you! Probably not Korea-based, but 1st class Haskell hackers: http://www.well-typed.com/ Sincerely, Gour -- Gour | Zagreb, Croatia | GPG key: C6E7162D pgp9JAQZoQF3p.pgp Description: PGP signature ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] Is Arrow based FRP a subset of Classic FRP, at least conceptually/semantically?
Classic FRP (CFRP, like Fran, FAL, Reactive, Grapefruit?...) exposes signals as first class values. Arrow based FRP (AFRP, like Fruit, Yampa...) hides signals as first class values; instead the signal transformers are the first class values. Can I conclude that it would theoretically be possible to translate an AFRP function into a CFRP function? I.e. is AFRP a subset of CFRP? Thanks, Peter ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] nested function application question
Hello, I have the following: B.intercalate $ B.intercalate ByteString [ByteString] [ByteString] I get a type error with this. If I comment out the 2nd B.intercalate and the third parameter I get no type errors. Regards, Vasili ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] nested function application question
2009/1/5 Galchin, Vasili vigalc...@gmail.com: Hello, I have the following: B.intercalate $ B.intercalate ByteString [ByteString] [ByteString] I get a type error with this. If I comment out the 2nd B.intercalate and the third parameter I get no type errors. B.intercalate needs a ByteString and a list of ByteStrings. Two B.intercalates need two ByteStrings and two lists of ByteStrings. --Max ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] nested function application question
Hi Max, That is what should happen The inner B.intercalate will produce the ByteString to be used by the B.intercalate. ?? Vasili On Mon, Jan 5, 2009 at 12:13 PM, Max Rabkin max.rab...@gmail.com wrote: 2009/1/5 Galchin, Vasili vigalc...@gmail.com: Hello, I have the following: B.intercalate $ B.intercalate ByteString [ByteString] [ByteString] I get a type error with this. If I comment out the 2nd B.intercalate and the third parameter I get no type errors. B.intercalate needs a ByteString and a list of ByteStrings. Two B.intercalates need two ByteStrings and two lists of ByteStrings. --Max ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] nested function application question
Did you mean: B.intercalate (B.intercalate ByteString [ByteString]) [ByteString] ($) applies all the way to the right, so you were giving the inner intercalate two lists of ByteString. -Ross On Jan 5, 2009, at 1:17 PM, Galchin, Vasili wrote: Hi Max, That is what should happen The inner B.intercalate will produce the ByteString to be used by the B.intercalate. ?? Vasili On Mon, Jan 5, 2009 at 12:13 PM, Max Rabkin max.rab...@gmail.com wrote: 2009/1/5 Galchin, Vasili vigalc...@gmail.com: Hello, I have the following: B.intercalate $ B.intercalate ByteString [ByteString] [ByteString] I get a type error with this. If I comment out the 2nd B.intercalate and the third parameter I get no type errors. B.intercalate needs a ByteString and a list of ByteStrings. Two B.intercalates need two ByteStrings and two lists of ByteStrings. --Max ___ 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] Re: Use of abbreviations in Haskell
Ketil Malde ke...@malde.org wrote: Implicit importing: submodule syntax implies adding an import The.Module.Name line at that point in the containing file. I'm not sure I agree with that, I don't see why we shouldn't treat these modules as ordinary modules. One of the motivations for doing this is to qualify record labels - not being able to specify import .. qualified or as ... seems like rather a loss. import [qualified] module Foo [as F] [hiding(baz)] where bar = undefined baz = bar OTOH, the Ocaml folks are going to ridicule us even more. Now they redid the module system, and it's still second-class -- (c) this sig last receiving data processing entity. Inspect headers for copyright history. All rights reserved. Copying, hiring, renting, performance and/or quoting of this signature prohibited. ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] nested function application question
On Mon, Jan 5, 2009 at 10:17 AM, Galchin, Vasili vigalc...@gmail.com wrote: Hi Max, That is what should happen The inner B.intercalate will produce the ByteString to be used by the B.intercalate. ?? Vasili Of course. My mistake. Ross Mellgren seems to be on the money though. --Max ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] nested function application question
yep ... that is exactly what I meant!! so can I use more $'s or must I use parens (as you did) to disambiguate? Vasili On Mon, Jan 5, 2009 at 12:18 PM, Ross Mellgren rmm-hask...@z.odi.ac wrote: Did you mean: B.intercalate (B.intercalate ByteString [ByteString]) [ByteString] ($) applies all the way to the right, so you were giving the inner intercalate two lists of ByteString. -Ross On Jan 5, 2009, at 1:17 PM, Galchin, Vasili wrote: Hi Max, That is what should happen The inner B.intercalate will produce the ByteString to be used by the B.intercalate. ?? Vasili On Mon, Jan 5, 2009 at 12:13 PM, Max Rabkin max.rab...@gmail.com wrote: 2009/1/5 Galchin, Vasili vigalc...@gmail.com: Hello, I have the following: B.intercalate $ B.intercalate ByteString [ByteString] [ByteString] I get a type error with this. If I comment out the 2nd B.intercalate and the third parameter I get no type errors. B.intercalate needs a ByteString and a list of ByteStrings. Two B.intercalates need two ByteStrings and two lists of ByteStrings. --Max ___ 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] nested function application question
In this case you have to use parens -- two dollar signs, like this B.intercalate $ B.intercalate ByteString [ByteString] $ [ByteString] would also not type check -- it is exactly equivalent to your first example: B.intercalate (B.intercalate ByteString [ByteString] ([ByteString])) just with one level of extra parentheses. If for some reason you absolutely need to avoid parentheses (mostly as a thought exercise, I guess), you'd have to have a flipped version of intercalate: flippedIntercalate :: [ByteString] - ByteString - ByteString flippedIntercalate = flip B.intercalate flippedIntercalate [ByteString] $ B.intercalate ByteString [ByteString] of course, this is pretty contrived. -Ross On Jan 5, 2009, at 1:23 PM, Galchin, Vasili wrote: yep ... that is exactly what I meant!! so can I use more $'s or must I use parens (as you did) to disambiguate? Vasili On Mon, Jan 5, 2009 at 12:18 PM, Ross Mellgren rmm- hask...@z.odi.ac wrote: Did you mean: B.intercalate (B.intercalate ByteString [ByteString]) [ByteString] ($) applies all the way to the right, so you were giving the inner intercalate two lists of ByteString. -Ross On Jan 5, 2009, at 1:17 PM, Galchin, Vasili wrote: Hi Max, That is what should happen The inner B.intercalate will produce the ByteString to be used by the B.intercalate. ?? Vasili On Mon, Jan 5, 2009 at 12:13 PM, Max Rabkin max.rab...@gmail.com wrote: 2009/1/5 Galchin, Vasili vigalc...@gmail.com: Hello, I have the following: B.intercalate $ B.intercalate ByteString [ByteString] [ByteString] I get a type error with this. If I comment out the 2nd B.intercalate and the third parameter I get no type errors. B.intercalate needs a ByteString and a list of ByteStrings. Two B.intercalates need two ByteStrings and two lists of ByteStrings. --Max ___ 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] nested function application question
2009/1/5 Ross Mellgren rmm-hask...@z.odi.ac: If for some reason you absolutely need to avoid parentheses (mostly as a thought exercise, I guess), you'd have to have a flipped version of intercalate: Or a version of ($) that associates differently. infixl 0 $$ f $$ x = f x *Main Data.ByteString :t \x y z - intercalate $$ intercalate x y $$ z \x y z - intercalate $$ intercalate x y $$ z :: ByteString - [ByteString] - [ByteString] - ByteString -- Dave Menendez d...@zednenem.com http://www.eyrie.org/~zednenem/ ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] nested function application question
Thank you everybody! Vasili On Mon, Jan 5, 2009 at 12:57 PM, David Menendez d...@zednenem.com wrote: 2009/1/5 Ross Mellgren rmm-hask...@z.odi.ac: If for some reason you absolutely need to avoid parentheses (mostly as a thought exercise, I guess), you'd have to have a flipped version of intercalate: Or a version of ($) that associates differently. infixl 0 $$ f $$ x = f x *Main Data.ByteString :t \x y z - intercalate $$ intercalate x y $$ z \x y z - intercalate $$ intercalate x y $$ z :: ByteString - [ByteString] - [ByteString] - ByteString -- Dave Menendez d...@zednenem.com http://www.eyrie.org/~zednenem/ http://www.eyrie.org/%7Ezednenem/ ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] Re: Use of abbreviations in Haskell
Ketil Malde ke...@malde.org wrote: Achim Schneider bars...@web.de writes: import [qualified] module Foo [as F] [hiding(baz)] where bar = undefined baz = bar Why do you want the 'where' there? Why not simply treat a file Foo.Bar as a concatenation of module Foo.Bar and optionally modules Foo.Bar.*? Because the module definition syntax is module Foo[(exports] where... technically, it's not necessary, but it's nice. OTOH, the Ocaml folks are going to ridicule us even more. Now they redid the module system, and it's still second-class Well, they would be wrong, wouldn't they? I don't want to redo the module system, and in fact, I think my proposal wouldn't change the language at all, merely how the compiler searches for modules. (Which it would be nice if the compilers agreed upon, of course.) It's just that inline modules, especially that syntax above, reminded me of Ocaml. It's not far from there to foo = module Foo where bar = undefined import foo -- (c) this sig last receiving data processing entity. Inspect headers for copyright history. All rights reserved. Copying, hiring, renting, performance and/or quoting of this signature prohibited. ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Will GHC finally support epoll in 2009?
On Thu, Jan 1, 2009 at 8:32 PM, Bryan O'Sullivan b...@serpentine.com wrote: On Wed, Dec 31, 2008 at 11:42 AM, Levi Greenspan greenspan.l...@googlemail.com wrote: Hence my question - is it likely that GHC will support epoll in 2009? Yes. I'm working on a patch at the moment. Awesome! Please post to this list when you have any news or updates. Thanks, Bit ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Is Arrow based FRP a subset of Classic FRP, at least conceptually/semantically?
On Mon, Jan 5, 2009 at 10:09 AM, Peter Verswyvelen bugf...@gmail.comwrote: Classic FRP (CFRP, like Fran, FAL, Reactive, Grapefruit?...) exposes signals as first class values. Arrow based FRP (AFRP, like Fruit, Yampa...) hides signals as first class values; instead the signal transformers are the first class values. Can I conclude that it would theoretically be possible to translate an AFRP function into a CFRP function? I.e. is AFRP a subset of CFRP? Why don't you check yourself? AFRP, if I recall correctly, has Arrow and ArrowLoop. So the combinators we need follow: Using a ~ b as shorthand for Behavior a - Behavior b. -- From Arrow arr :: (a - b) - (a ~ b) first :: (a ~ b) - ((a,c) ~ (b,c)) () :: (a ~ b) - (b ~ c) - (a ~ c) arr = fmap first f ac = liftA2 (,) (f (fst $ ac)) (snd $ ac) () = () -- From ArrowLoop loop :: ((a,c) ~ (b,c)) - (a ~ b) loop f a = let bc = f (liftA2 (,) a (snd $ bc)) in fst $ bc So that's a positive on all the arrow combinators. You have to check the supplied primitives, too, such as integral and pswitch. Once you do that, you could even implement a ClassicFRP arrow and use that instead of the Yampa arrow, so the client code wouldn't need to be changed at all. What I have just described is the ideal situation. Here are some of the practicalities you might run into: * AFRP models events as signals of Maybe. Semantically speaking, signals of Maybe don't have nice eventy properties, such as discrete occurrences, so you might have some difficulty translating between the two. I'm currently exploring an arrow model that accounts for events properly, but that probably doesn't help you. * The above loop combinator is key to eliminating quadratic behavior in certain classic FRP situations, and I believe the reason arrows were explored to begin with. See Plugging a Space Leak with an Arrow by Hudak and Liu[1] for more. In Fran-like systems, there is another fix for this leak, in exchange for loss of perfect reactivity (making a discrete memo table of sorts). [1] www.cs.yale.edu/~hl293/download/*leak*.pdfhttp://www.cs.yale.edu/%7Ehl293/download/leak.pdf Thanks, Peter ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Type Family Relations
Generalizing the previous post, with: - {-# LANGUAGE GADTs #-} module Equ where data a:==:b where Equ :: (a ~ b) = a:==:b symm :: (a:==:a) symm = Equ refl :: (a:==:b) - (b:==:a) refl Equ = Equ trans :: (a:==:b) - (b:==:c) - (a:==:c) trans Equ Equ = Equ cast :: (a:==:b) - (a - b) cast Equ = id - We can do (e.g.): data IPv4Header = C1 data IPv4 = C2 type instance HeaderOf IPv4 = IPv4Header type instance AddressOf IPv4Header = IPv4 t0 :: IPv4 :==: AddressOf IPv4Header t0 = Equ t1 :: IPv4Header :==: HeaderOf IPv4 t1 = Equ t2 :: IPv4 :==: AddressOf (HeaderOf IPv4) t2 = Equ t3 :: IPv4Header :==: HeaderOf (AddressOf IPv4Header) t3 = Equ -- And interestingly `t6' shows that the type family option -- in the previous case is slightly stronger that the funcdeps -- option, ie the type fams one corresponds to the funcdeps -- addr - hdr, hdr - addr (instead of the weaker addr - hdr). -- If this isn't desired I'd bet there's a way to modify the type -- instances to get the desired behavior. t5 :: AddrHdrPair a b - a :==: AddressOf (HeaderOf a) t5 AddrHdrPair = Equ t6 :: AddrHdrPair a b - b :==: HeaderOf (AddressOf b) t6 AddrHdrPair = Equ Matt ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] Re: Use of abbreviations in Haskell
Achim Schneider bars...@web.de wrote: Ketil Malde ke...@malde.org wrote: Achim Schneider bars...@web.de writes: import [qualified] module Foo [as F] [hiding(baz)] where bar = undefined baz = bar Why do you want the 'where' there? Why not simply treat a file Foo.Bar as a concatenation of module Foo.Bar and optionally modules Foo.Bar.*? Because the module definition syntax is module Foo[(exports] where... technically, it's not necessary, but it's nice. Additionally, I don't think concatenation works well here, n-ary trees work better. module Foo where import module Bar where import module Baz where quux = undefined quux' = quux . quux quux'' = quux' . quux' quux''' = quux'' . quux'' would be nice. -- (c) this sig last receiving data processing entity. Inspect headers for copyright history. All rights reserved. Copying, hiring, renting, performance and/or quoting of this signature prohibited. ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] nested function application question
On Mon, Jan 5, 2009 at 3:16 PM, Brandon S. Allbery KF8NH allb...@ece.cmu.edu wrote: On 2009 Jan 5, at 13:57, David Menendez wrote: 2009/1/5 Ross Mellgren rmm-hask...@z.odi.ac: If for some reason you absolutely need to avoid parentheses (mostly as a thought exercise, I guess), you'd have to have a flipped version of intercalate: Or a version of ($) that associates differently. infixl 0 $$ f $$ x = f x *Main Data.ByteString :t \x y z - intercalate $$ intercalate x y $$ z \x y z - intercalate $$ intercalate x y $$ z :: ByteString - [ByteString] - [ByteString] - ByteString ...at which point we're reinventing Applicative, no? Is const a reinvention of return? You could write the above code with (*), but you'd need to convert back and forth from Identity in order to get the proper Applicative instance. runIdentity $ Identity B.intercalate * Identity (B.intercalate x y) * Identity z At that point, you might as well save the noise and write, B.intercalate (B.intercalate x y) z -- Dave Menendez d...@zednenem.com http://www.eyrie.org/~zednenem/ ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] Re: #haskell IRC channel reaches 600 users
Robin Green gree...@greenrd.org wrote: Whereas, each of these academics might be oblivious (or almost oblivious) to the other two critiques. And a load full of arguments why those other critiques are irrelevant? ;) -- (c) this sig last receiving data processing entity. Inspect headers for copyright history. All rights reserved. Copying, hiring, renting, performance and/or quoting of this signature prohibited. ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Re: Use of abbreviations in Haskell
Achim Schneider bars...@web.de writes: import [qualified] module Foo [as F] [hiding(baz)] where bar = undefined baz = bar Why do you want the 'where' there? Because the module definition syntax is module Foo[(exports] where... technically, it's not necessary, but it's nice. Right - I missed the 'module' and just read it as an import statement. Clearly your proposal here goes beyond mine, what are the advantages? I.e, what's the rationale for syntactical changes instead of simply treat[ing] a file Foo.Bar as a concatenation of module Foo.Bar and optionally modules Foo.Bar.*? -k -- If I haven't seen further, it is by standing in the footprints of giants ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] nested function application question
On 2009 Jan 5, at 13:57, David Menendez wrote: 2009/1/5 Ross Mellgren rmm-hask...@z.odi.ac: If for some reason you absolutely need to avoid parentheses (mostly as a thought exercise, I guess), you'd have to have a flipped version of intercalate: Or a version of ($) that associates differently. infixl 0 $$ f $$ x = f x *Main Data.ByteString :t \x y z - intercalate $$ intercalate x y $ $ z \x y z - intercalate $$ intercalate x y $$ z :: ByteString - [ByteString] - [ByteString] - ByteString ...at which point we're reinventing Applicative, no? -- brandon s. allbery [solaris,freebsd,perl,pugs,haskell] allb...@kf8nh.com system administrator [openafs,heimdal,too many hats] allb...@ece.cmu.edu electrical and computer engineering, carnegie mellon universityKF8NH ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Trouble with interact in ghci
Hi Adrian On Wed, Dec 17, 2008 at 11:44:14AM +0100, Adrian Neumann wrote: I have a strange problem with interact on OS X (ghc 6.10.1). It seems to garble stdin. See the After using getContents section of http://www.haskell.org/ghc/docs/latest/html/users_guide/ghci-faq.html Thanks Ian ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Portability of MonadError
On Mon, Jan 5, 2009 at 1:48 PM, Peter Robinson thaldy...@gmail.com wrote: Hello, One thing that's been bothering me about MonadError monads is the non-portability of code that uses a custom Error type. Meaning, if I have libraries A and B that use different error types, I won't be able to write a function func: func = (funcA funcB) `catchError` (\e - ...) funcA :: ErrorT MyErrorA m () funcB :: ErrorT MyErrorB m () So I'm wondering whether there's a reason not to introduce a type class hierarchy instead of custom error types to make the code more portable. I think this worry is related to a world view of large monads, which also proliferates claims like monads are not appropriate for large programs, and is related to fat interfaces in OOP. I claim that, like objects, monads are appropriate for little pieces of computations, and monadic computations in different monads deserve to be composed just as much so as those in the same monad. The complex type-directed approach gives the feel of exceptions from mainstream languages, but will run into problems when eg. two computations both use ErrorT String, but you want to differentiate the errors. All that is necessary is a simple function: mapError :: (e - e') - ErrorT e a - ErrorT e' a mapError f = ErrorT . liftM (left f) . runErrorT (Where left is from Control.Arrow, and is a semantic editor) Then your example can become:: func = (mapError Left funcA mapError Right funcB) `catchError` (\e - ...) Luke ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Portability of MonadError
On Mon, Jan 5, 2009 at 2:13 PM, Luke Palmer lrpal...@gmail.com wrote: On Mon, Jan 5, 2009 at 1:48 PM, Peter Robinson thaldy...@gmail.comwrote: Hello, One thing that's been bothering me about MonadError monads is the non-portability of code that uses a custom Error type. Meaning, if I have libraries A and B that use different error types, I won't be able to write a function func: func = (funcA funcB) `catchError` (\e - ...) funcA :: ErrorT MyErrorA m () funcB :: ErrorT MyErrorB m () So I'm wondering whether there's a reason not to introduce a type class hierarchy instead of custom error types to make the code more portable. I think this worry is related to a world view of large monads, which also proliferates claims like monads are not appropriate for large programs, and is related to fat interfaces in OOP. I claim that, like objects, monads are appropriate for little pieces of computations, and monadic computations in different monads deserve to be composed just as much so as those in the same monad. The complex type-directed approach gives the feel of exceptions from mainstream languages, but will run into problems when eg. two computations both use ErrorT String, but you want to differentiate the errors. All that is necessary is a simple function: mapError :: (e - e') - ErrorT e a - ErrorT e' a mapError f = ErrorT . liftM (left f) . runErrorT Modulo obvious errors, as usual. Haskell type inference knows better than I do: mapError :: Monad m = (e - e') - ErrorT e m a - ErrorT e' m a Luke (Where left is from Control.Arrow, and is a semantic editor) Then your example can become:: func = (mapError Left funcA mapError Right funcB) `catchError` (\e - ...) Luke ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Infinite grid
I think I found a solution to this, if you're still looking for one. See attached code. It uses a rose tree zipper where tree depth is manhattan distance from origin and forest width is nodes around concentric diamonds. The code is straightforward. Polar coords (RK) are stored in node label, with conversion to/from cartesian calculated on the fly (but may also be stored in label if speed is more important than time). Cyclic closed loop tests like your f below run in constant space for me. Dan Weston Martijn van Steenbergen wrote: Hello, I would like to construct an infinite two-dimensional grid of nodes, where a node looks like this: data Node = Node { north :: Node , east :: Node , south :: Node , west :: Node } in such a way that for every node n in the grid it doesn't matter how I travel to n, I always end up in the same memory location for that node. I suspect another way of saying that is that let f = f . north . east . south . west in f origin should run in constant space. I hope this makes the problem clear. :-) How do I do this? Thanks in advance, Martijn. -- |2-D infinite grid with O(1) lookup, modification, and incremental move -- -- Data is saved sparsely (wrapped in Maybe) with a rose tree zipper -- where depth is manhattan distance from origin, and sibling index is order -- CCW around a diamond centered at origin. Sparsity maximized by storing -- only nonempty nodes (save that every radius below max has at least one node). -- -- Uses Data.Tree.Zipper which can be found on hackage at -- http://hackage.haskell.org/cgi-bin/hackage-scripts/package/rosezipper -- -- Data.Tree is indexed by Int. For unbounded grid, rewrite this code, -- Data.Tree, and Data.Tree.Zipper to use Integer (should be straightforward). -- -- Copyright (c) Dan Weston, 2008. All rights reserved. -- -- License: Simplified BSD. See bottom of source file for details. module GridZipper ( -- * Grid representation module Data.Tree, module Data.Tree.Zipper, GridLabel(..), Grid, GridZipper, newGrid, -- * Grid coordinates XY(..), RK(..), getRK,getXY, cartesianFromPolar,polarFromCartesian, -- * Grid values getValue,newValue,setValue, -- * Moving around the grid goToRK,goToXY,moveInXY,north,south,east,west, -- * Example usage assocList,sampleUsage ) where import Data.Tree.Zipper(TreeLoc,getLabel,setLabel,modifyLabel, root,parent,left,right,firstChild,toTree,fromTree, insertRight,insertDownFirst) import Data.Tree (Tree,flatten) import Data.Maybe (maybe,isJust,fromJust) -- -- DATA TYPES -- -- |Cartesian grid coordinates data XY = XY Int Int deriving (Eq,Show) -- |Polar grid coordinates -- r = |x| + |y| (manhattan distance form origin) -- k = index around diamond, starting at (+r,0) data RK = RK Int Int deriving (Eq,Show) -- |Grid label data GridLabel a = GridLabel RK (Maybe a) deriving (Eq,Show) -- |Grid represented as rose tree (radius = depth, angle = width) type Grid a = Tree(GridLabel a) -- |Cursor is rose tree zipper (polar coords stored in label alongside value) type GridZipper a = TreeLoc (GridLabel a) -- -- COORDINATE CONVERSION -- -- |Gets cartesian coordinates from polar ones cartesianFromPolar :: RK - XY cartesianFromPolar (RK 0 0) = XY 0 0 cartesianFromPolar (RK r k) = case q of 0 - XY (r - s ) (s ) 1 - XY (negate s) (r - s ) 2 - XY (s - r ) (negate s) 3 - XY (s ) (s - r ) where (q,s) = k `divMod` r -- |Gets polar coordinates from cartesian ones polarFromCartesian :: XY - RK polarFromCartesian (XY 0 0) = RK 0 0 polarFromCartesian (XY x y) | x 0 y = 0 = RK ry | y 0 x = 0 = RK r (r - x) | x 0 y = 0 = RK r (2*r - y) | y 0 x = 0 = RK r (3*r + x) where r = abs x + abs y -- -- COORDINATE ACCESS -- -- |Extracts polar coordinates from label getRK :: GridLabel a - RK getRK (GridLabel rk _) = rk -- |Extracts cartesian coordinates from label getXY :: GridLabel a - XY getXY = cartesianFromPolar . getRK -- -- VALUE ACCESS AND MODIFY -- -- |Extracts grid value, if any, from label getValue :: GridLabel a - Maybe a getValue (GridLabel _ value) = value -- |Returns copy, replacing grid value newValue :: Maybe a - GridLabel a - GridLabel a newValue v (GridLabel rk _) = GridLabel rk v -- |Returns copy, replacing grid value
Re: [Haskell-cafe] Portability of MonadError
On Mon, Jan 5, 2009 at 2:13 PM, Luke Palmer lrpal...@gmail.com wrote: On Mon, Jan 5, 2009 at 1:48 PM, Peter Robinson thaldy...@gmail.com wrote: Hello, One thing that's been bothering me about MonadError monads is the non-portability of code that uses a custom Error type. Meaning, if I have libraries A and B that use different error types, I won't be able to write a function func: func = (funcA funcB) `catchError` (\e - ...) funcA :: ErrorT MyErrorA m () funcB :: ErrorT MyErrorB m () So I'm wondering whether there's a reason not to introduce a type class hierarchy instead of custom error types to make the code more portable. I think this worry is related to a world view of large monads, which also proliferates claims like monads are not appropriate for large programs, and is related to fat interfaces in OOP. I claim that, like objects, monads are appropriate for little pieces of computations, and monadic computations in different monads deserve to be composed just as much so as those in the same monad. Well my main concern was that composability issue of similar (modulo error type) monads. The complex type-directed approach gives the feel of exceptions from mainstream languages, but will run into problems when eg. two computations both use ErrorT String, but you want to differentiate the errors. Not sure I got this: When using the type class approach you would not use an instantiation like ErrorT String in code intended to be portable, but rather something like ErrorT MyClass. Either two computations have the same error type class or they don't, so there shouldn't be any problem differentiating errors, right? All that is necessary is a simple function: mapError :: (e - e') - ErrorT e a - ErrorT e' a mapError f = ErrorT . liftM (left f) . runErrorT Modulo obvious errors, as usual. Haskell type inference knows better than I do: mapError :: Monad m = (e - e') - ErrorT e m a - ErrorT e' m a Luke (Where left is from Control.Arrow, and is a semantic editor) Then your example can become:: func = (mapError Left funcA mapError Right funcB) `catchError` (\e - ...) Yes that does look interesting. Thanks for the hint! Peter ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Portability of MonadError
On Mon, Jan 5, 2009 at 2:13 PM, Luke Palmer lrpal...@gmail.com wrote: Then your example can become:: func = (mapError Left funcA mapError Right funcB) `catchError` (\e - ...) Luke Oh bother! My new year's resolution: think before I speak. While I do think this is the right answer, it is not the right answer in the status quo. This is because ErrorT e m is only a monad when e is an Error, which Either (and most types) are not. It will be the right answer when fail is factored out of Monad into MonadFail (which will happen someday hopefully), because then the typechecker will verify that the above composition cannot fail. But now I can't think of a good answer. Darn. Luke ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Portability of MonadError
On Mon, 5 Jan 2009, Luke Palmer wrote: Oh bother! My new year's resolution: think before I speak. While I do think this is the right answer, it is not the right answer in the status quo. This is because ErrorT e m is only a monad when e is an Error, which Either (and most types) are not. It will be the right answer when fail is factored out of Monad into MonadFail (which will happen someday hopefully), because then the typechecker will verify that the above composition cannot fail. But now I can't think of a good answer. Darn. In the explicit-exception package I omit 'fail' and allow an exception type without constraints.___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Re: GHC 6.10.1 for Solaris i86
On Tue, Dec 16, 2008 at 04:24:25PM +0100, Christian Maeder wrote: Donald Halomoan wrote: I am waiting for GHC 6.10. 1 binary for Solaris i86. Thanks. You could try mine: http://www.informatik.uni-bremen.de/agbkb/forschung/formal_methods/CoFI/hets/pc-solaris/ghcs/ghc-6.10.1-i386-unknown-solaris2.tar.bz2 it needs libedit.so.0 and libncurses.so.5 Thanks Christian - I've added this to the 6.10.1 download page. Thanks Ian ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
[Haskell-cafe] Maybe a compiler bug?
When using any of -O, -O1, -O2 with the Debian binary build of GHC 6.6, trace shows that the expression if (lr ll) then False else True is (at least partially) evaluated, but the value returned is always True, even though trace reports that (lr ll) is True. When I use only the native code generator (without optimization), the correct value (False) is returned. Further detail and complete code on request. Best, Murray Gross ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Maybe a compiler bug?
On Mon, Jan 5, 2009 at 4:34 PM, Murray Gross mgros...@verizon.net wrote: When using any of -O, -O1, -O2 with the Debian binary build of GHC 6.6, trace shows that the expression if (lr ll) then False else True is (at least partially) evaluated, but the value returned is always True, even though trace reports that (lr ll) is True. When I use only the native code generator (without optimization), the correct value (False) is returned. Further detail and complete code on request. Of course! This is obviously incorrect behavior. Are you doing any unsafePerformIO? Please, complete code (minimal test case if possible, but don't let that stop you). Luke Best, Murray Gross ___ 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] Re: Updating doubly linked lists
For the 2D grid zipper above, moving around is O(1) but update is O(log n). This is acceptable; also because I'm quite confident that a zipper for a 2D grid with everything O(1) does not exist. I can prove that for a special case and should probably write it down at some point. Really? My solution (rose tree zipper where tree depth is manhattan distance from origin and forest width is nodes around concentric diamonds, see http://permalink.gmane.org/gmane.comp.lang.haskell.cafe/49948) was designed specifically to be amortized constant for everything for paths that do not specifically move helically around the origin. The complexity of lookup is O(d) where d is the number of defined nodes at a given radius. Until the grid gets pretty dense, d grows very slowly for most sane paths. Have I missed something? Dan Apfelmus, Heinrich wrote: S. Günther wrote: What kind of structure do you need exactly? What I really need is a structure which represents a two dimensional grid, i.e. it consists of nodes having a value and a list of neighbours attached to it. Point is that if node 1 has node 2 as a neighbour then node 2 has to have node 1 as a neighbour and each node has the same number of neighbours (currently 4, but may vary). Ah, so you have a rectangular (or later hexagonal?) 2D grid? I suggest representing it as Data.Map (Integer, Integer) a as explained below. That's why I said that thinking about the circular case was just a divergence that really got me wondering/interested which is why I posted the question in it's short form at the beginning. Exploring a related easier problem is always a good way to get some intuition for tackling the harder one. :) Anyways, back to the structure I need. One additional thing which will happen during the algorithm is that there will be updates to a certain local neighboruhood of a node. Now I understand, that that might very well be possible with zippers. Instead of lists of neighbouring nodes I might as well save the paths through the graphs separately from the nodes although I only have a very vague intuition about how that would look like. And instead of calculating a lists of nodes to update, I could calculate a path visting the nodes and update them (again beeing unable to escape from the prison of an imperative mindset) traversing the path. A zipper indeed allows you to move to neighbors and update them. But the point was that I just had a hard time generalizing what I read about zippers to structures where you can have embedded cycles, e.g. up . left . down . right = id. If you interpret zippers as the original data structure with a hole, this is not so difficult. For instance, consider a rectangular grid +--+--+--+--+--+--+--+ | | | | | | | | +--+--+--+--+--+--+--+ | | | | | | | | +--+--+--+--+--+--+--+ | | | | | | | | +--+--+--+--+--+--+--+ where you store some data at every node. Now, a zipper is just the old data structure but one node is marked as hole +--+--+--+--+--+--+--+ | | | | | | | | +--+--+--O--+--+--+--+ | | | | | | | | +--+--+--+--+--+--+--+ | | | | | | | | +--+--+--+--+--+--+--+ If you represent the grid as a rectangular table type Position = (Integer, Integer) type Grid a = Data.Map Position a a zipper is simply the grid with an extra marker type Zipper a = (Grid a, Position) left,right,up,down :: Zipper a - Zipper a left (g,(x,y)) = (g,(x-1,y)) right (g,(x,y)) = (g,(x+1,y)) up(g,(x,y)) = (g,(x,y-1)) down (g,(x,y)) = (g,(x,y+1)) update :: a - Zipper a - Zipper a update a (g,(x,y)) = (insert (x,y) a g, (x,y)) Note that the left, right etc. are not baked into the data type but implemented as normal functions. In principle, the same could be done for lists type ZipperL a = ([a], Int) left, right :: ZipperL a - ZipperL a left (xs,i) = (xs,i-1) right (xs,i) = (xs,i+1) update :: a - ZipperL a - ZipperL a update a (xs,i) = (take i xs ++ [a] ++ drop (i+1) xs, i) This is a valid implementation of a zipper for lists, but of course is very inefficient, update is O(n) . The key thing about the original list zipper with back and front list is that all operations are O(1). For the 2D grid zipper above, moving around is O(1) but update is O(log n). This is acceptable; also because I'm quite confident that a zipper for a 2D grid with everything O(1) does not exist. I can prove that for a special case and should probably write it down at some point. In other words, I suggest representing your grid as a Data.Map (Integer,Integer) a and accept the minor inconvenience of a O(log n) update. Choosing a different finite map implementation may give a better constant factor. For instance you can nest two Data.IntMap etc. Righty right, but there's still the possibility that given all the time in the world and the clearest explanations I'm just to dense to get a hold of it. That said I hope
[Haskell-cafe] ANN bytestring-trie 0.1.2 (bugfix)
-- bytestring-trie 0.1.2 (bugfix) Another bugfix release for efficient finite maps from (byte)strings to values. Release early, release often. -- Changes * Fixed a bug in alterBy pointed out by Mark Wotton. Same bug as the previous one pointed out by Maxime Henrion (a missing case). * Added an Eq instance, in case anyone cares. -- Links Homepage: http://code.haskell.org/~wren/ Hackage: http://hackage.haskell.org/cgi-bin/hackage-scripts/package/bytestring-trie Darcs: http://code.haskell.org/~wren/bytestring-trie/ Haddock (Darcs version): http://code.haskell.org/~wren/bytestring-trie/dist/doc/html/bytestring-trie/ -- Live well, ~wren ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Maybe a compiler bug?
No unsafe perform (except what may be hidden in trace), nothing, fancy, no gimmicks (very pedestrian, even heavy-handed) code. Complete code is attached (I don't have smaller snippets, because I just discovered the problem). Best, Murray Gross On Mon, 5 Jan 2009, Luke Palmer wrote: On Mon, Jan 5, 2009 at 4:34 PM, Murray Gross mgros...@verizon.net wrote: When using any of -O, -O1, -O2 with the Debian binary build of GHC 6.6, trace shows that the expression if (lr ll) then False else True is (at least partially) evaluated, but the value returned is always True, even though trace reports that (lr ll) is True. When I use only the native code generator (without optimization), the correct value (False) is returned. Further detail and complete code on request. Of course! This is obviously incorrect behavior. Are you doing any unsafePerformIO? Please, complete code (minimal test case if possible, but don't let that stop you). Luke Best, Murray Gross ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe -- * -- * * -- *Eternity II puzzle. Each puzzle piece is represented by a * -- *5-tuple, in which the first 4 entries represent the four * -- *edge colors in the order left, top, right, bottom, and the * -- *fifth member is the (numerical) identifier for the piece. * -- * * -- * -- module Solve where import Data.Array.IArray import Control.Parallel import Control.Parallel.Strategies import List import Debug.Trace main = putStrLn (show corns) putStrLn (corpic) putStrLn Left sides\n putStrLn (pArrayPic (pArray pSides)) putStrLn Right sides\n putStrLn (pArrayPic (rightArray )) putStrLn (show (length (perims (pArray pSides) corTemp))) putStrLn (show (perims (pArray pSides) corTemp)) putStrLn done -- * -- * * -- *Make a list of all possible perimeters. Run the operation in * -- *parallel over the list of possible corner configurations. * -- * * -- * perims:: Array (Int) [Int]- [(Int,Int,Int,Int)]-[[Int]] perims pArray corTemp = concat $ parMap rwhnf (\oneCor-makPerim oneCor pArray ) corTemp -- * -- * * -- *We build a list of perimeters by constructing each backward* -- *from position 59. However, position 59 needs special handling * -- *because it must match position 0 as well as 58. Each of the* -- *other corners will also need special handling, which is done * -- *by a case statement. * -- * * -- *Note that pArray is organized by the left sides of the pieces, * -- *while in makePerim we need to check the right side of a* -- *against the bottom of the first corner. This results in the* -- *need for rightArray, and some tricky indexing. * -- * * -- * makPerim :: (Int,Int,Int,Int) - Array (Int) [Int] - [[Int]] makPerim oneCor pArray = [a:b | a - ((rightArray) ! startCol), b - (restPerim a (pArray // [(left(refPerim!a), (pArray!(left(refPerim!a)))\\[a])]) (rightArray //[(startCol, (rightArray ! startCol) \\ [a])]) oneCor 58), trace (show b) b /=[] ] where startCol = bot (corns !! (fst4 oneCor)) -- * -- * * -- *Once past the first piece in a perimeter, move to next.* -- *Check for a corner piece,
[Haskell-cafe] Can I destructive rebind a local variable in haskell?
Dear haskeller, Can I destructive rebind a local variable like this import System.Directory test filename = do is_dir - doesDirectoryExist filename let filename = if not is_dir then filename else filename putStrLn $ filename ++ filename main = test . in GHCi 6.10.1 on WinXP, the ghci aborts silencely when I executes main after compile it into a executable file. c:\USERS\home\learning_haskell\testDirectory testDirectory C stack overflow in generated code I have some code in scheme which works very well (define (func x) (let ((x x)) x)) By rebinding a formal variable, we can save naming some varaibles. I am not good at naming a variable. Thank you in advance Best Regards Chunye Wang chunye.w...@nsn.com ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Re: [Haskell-cafe] Can I destructive rebind a local variable in haskell?
2009/1/6 Wang, Chunye (NSN - CN/Beijing) chunye.w...@nsn.com Dear haskeller, Can I destructive rebind a local variable like this import System.Directory test filename = do is_dir - doesDirectoryExist filename let filename = if not is_dir then filename else filename Nope. The filename on the right side of the = is the same as the filename on the left, so you're making an infinite loop, the same way: let x = x in x is an infinite loop. However you can make a new name as you are trying, you just can't reference the old one. e.g.: let filename = 42 Here would be just fine. However, for cases like this, it is useful that single quote is a valid identifier, so you can say: let filename' = if not is_dir then filename else filename (read filename prime) Luke ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
RE: [Haskell-cafe] Can I destructive rebind a local variable in haskell?
Hi Luke Thank you ! I got it :) Best Regards Chunye Wang chunye.w...@nsn.com From: ext Luke Palmer [mailto:lrpal...@gmail.com] Sent: Tuesday, January 06, 2009 3:44 PM To: Wang, Chunye (NSN - CN/Beijing) Cc: Haskell-Cafe@haskell.org Subject: Re: [Haskell-cafe] Can I destructive rebind a local variable in haskell? 2009/1/6 Wang, Chunye (NSN - CN/Beijing) chunye.w...@nsn.com Dear haskeller, Can I destructive rebind a local variable like this import System.Directory test filename = do is_dir - doesDirectoryExist filename let filename = if not is_dir then filename else filename Nope. The filename on the right side of the = is the same as the filename on the left, so you're making an infinite loop, the same way: let x = x in x is an infinite loop. However you can make a new name as you are trying, you just can't reference the old one. e.g.: let filename = 42 Here would be just fine. However, for cases like this, it is useful that single quote is a valid identifier, so you can say: let filename' = if not is_dir then filename else filename (read filename prime) Luke ___ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe