Send Beginners mailing list submissions to beginners@haskell.org To subscribe or unsubscribe via the World Wide Web, visit http://www.haskell.org/mailman/listinfo/beginners or, via email, send a message with subject or body 'help' to beginners-requ...@haskell.org
You can reach the person managing the list at beginners-ow...@haskell.org When replying, please edit your Subject line so it is more specific than "Re: Contents of Beginners digest..." Today's Topics: 1. Re: Pointfree expeiments (Ertugrul Soeylemez) 2. Re: Question about data structures (Brent Yorgey) 3. Random computation with fixed seed value (Control.Monad.Random) (Jan Snajder) 4. Re: Random computation with fixed seed value (Control.Monad.Random) (Daniel Fischer) 5. Re: Random computation with fixed seed value (Control.Monad.Random) (Jan Snajder) ---------------------------------------------------------------------- Message: 1 Date: Thu, 25 Nov 2010 20:15:07 +0100 From: Ertugrul Soeylemez <e...@ertes.de> Subject: [Haskell-beginners] Re: Pointfree expeiments To: beginners@haskell.org Message-ID: <20101125201507.73c95...@tritium.streitmacht.eu> Content-Type: text/plain; charset=US-ASCII Ozgur Akgun <ozgurak...@gmail.com> wrote: > I don't know whether this is related or not, but I have the following > somewhere in my code: > > -- the following is apparently eqivalent to (\ i -> foo (bar i) i). > -- pointfree suggests so. i don't understand why. > (foo =<< bar) > > Is this a similar situation? Yes, it is. In the reader monad a computation is a function of one argument: foo :: a -> e -> b bar :: e -> a Running such a computation means passing a specific argument 'e' to all those functions and regarding monadic bindings like normal let bindings. Let me write this in 'do' syntax, so it gets clearer: do x <- bar foo x becomes: let x = bar e in foo x e I found the reader monad most useful in applicative style: splits :: [a] -> [([a], [a])] splits = zip <$> inits <*> tails Greets, Ertugrul -- nightmare = unsafePerformIO (getWrongWife >>= sex) http://ertes.de/ ------------------------------ Message: 2 Date: Thu, 25 Nov 2010 15:40:18 -0500 From: Brent Yorgey <byor...@seas.upenn.edu> Subject: Re: [Haskell-beginners] Question about data structures To: beginners@haskell.org Message-ID: <20101125204017.ga12...@seas.upenn.edu> Content-Type: text/plain; charset=iso-8859-1 On Thu, Nov 25, 2010 at 09:12:05AM -0800, Russ Abbott wrote: > Thanks, Patrick. I'm disappointed, though, that no one has > actually responded to my question. It wasn't how to solve KenKen. It was how > best to deal with quasi-mutable data structures. > * > -- Russ * Someone did respond to your question, with a link to the data-accessor package on Hackage (you could also take a look at fclabels or lenses). Do those help address your issue? -Brent > > > > On Thu, Nov 25, 2010 at 6:17 AM, Patrick LeBoutillier < > patrick.leboutill...@gmail.com> wrote: > > > Russ, > > > > If I understand correctly KenKen is something like Sudoku except that > > the (more complicated) "cages" > > constraints replace the usual "square" constraints. > > > > Have you seen these sudoku solvers: > > http://www.haskell.org/haskellwiki/Sudoku ? > > > > Maybe you can get ideas there on how to attack the problem in a more > > functional fashion. > > > > > > Patrick > > > > > > On Wed, Nov 24, 2010 at 9:58 PM, Russ Abbott <russ.abb...@gmail.com> > > wrote: > > > My previous two messages suggest a Haskell coding principle: distinguish > > > between fixed and (quasi-)mutable data structures. (I know values don't > > > change, but I hope you understand what I mean. The cage and the cell in > > my > > > previous example are quasi-mutable. They are conceptually mutable in the > > > context of the problem.) The fixed data structures can be organized any > > way > > > one wants. The quasi-/conceptually-mutable elements should be referred to > > > symbolically and stored in a Map. The maps themselves should be stored at > > a > > > global level of the system's data structure so that it is easy to replace > > > them when values change. > > > > > > -- Russ > > > > > > > > > On Wed, Nov 24, 2010 at 5:54 PM, Russ Abbott <russ.abb...@gmail.com> > > wrote: > > >> > > >> Actually using a Map does solve the problem. The Map has to be kept at > > the > > >> level of the Tree rather than have each leaf node point to it. So > > instead > > >> of just a Tree one has, say (Map, Tree). Then when one wants to change > > the > > >> property of something associated with a leaf node, one can just change > > the > > >> map. The Tree is unchanged. > > >> > > >> -- Russ > > >> > > >> > > >> > > >> On Wed, Nov 24, 2010 at 2:02 PM, Russ Abbott <russ.abb...@gmail.com> > > >> wrote: > > >>> > > >>> OK. So putting a Map at Leaf nodes doesn't solve the problem. > > >>> (Apparently I haven't been able to communicate what I see as the > > problem.) > > >>> The problem that I'm trying to get to is the need to write excessive > > code > > >>> for something that would require a lot less code in an OO world. It's > > not a > > >>> matter of execution time or space. It's a matter of the amount of code > > one > > >>> is required to write. > > >>> -- Russ > > >>> > > >>> > > >>> On Wed, Nov 24, 2010 at 1:52 PM, Daniel Fischer > > >>> <daniel.is.fisc...@web.de> wrote: > > >>>> > > >>>> On Wednesday 24 November 2010 22:12:37, Russ Abbott wrote: > > >>>> > Cool. I wasn't aware of that notation. It doesn't quite get to the > > >>>> > issue though. > > >>>> > > > >>>> > The problem I'm concerned about is the need to define y in the first > > >>>> > place. If one is chasing through a data structure and finds a need > > to > > >>>> > change something buried within it, it seems necessary to rebuild > > >>>> > everything that includes the changed thing. > > >>>> > > >>>> In general, values are immutable, so you can't "change something > > buried > > >>>> within it". You have to build a new value containing some of the old > > >>>> stuff > > >>>> and a new part. Building the new value usually consists mostly of > > >>>> copying a > > >>>> couple of pointers (plus building the new part of course), so isn't > > too > > >>>> expensive normally. > > >>>> > > >>>> You can have mutable values in the IO or (ST s) monads, if you need > > >>>> them. > > >>>> > > >>>> > That is, I can't change a > > >>>> > component of somethingNew without creating y. The point is there's > > >>>> > nothing about x that changed, > > >>>> > > >>>> The thing with the changed component is not x anymore. > > >>>> > > >>>> > and there may be nothing about (var1 x) > > >>>> > that changed, and there may be nothing about var11 . var1 $ x that > > >>>> > changed, etc. Yet one is apparently forced to keep track of and > > >>>> > reconstruct all those elements. > > >>>> > > >>>> The compiler takes care of that. > > >>>> > > >>>> > > > >>>> > Another example is to imagine a Tree in which the leaves contain > > >>>> > "objects." If I want to change a property of one of those leaf > > >>>> > objects, > > >>>> > > >>>> You can't in general, the thing with a different property is a > > different > > >>>> object. > > >>>> > > >>>> > I am forced to rebuild all the ancestor nodes of that leaf down to > > >>>> > rebuilding the root. > > >>>> > > >>>> Yes (well, not you, the compiler does it), except if your tree > > contains > > >>>> mutable objects (IORefs/STRefs for example). > > >>>> > > >>>> > > > >>>> > One way to avoid that is for the leaves to refer to their objects > > >>>> > through a Map. Then changing a leaf object requires only that the > > >>>> > value > > >>>> > associated with key represented by the leaf be (re-)inserted into > > the > > >>>> > Map. The Tree itself need not change at all. > > >>>> > > >>>> Oh, it will. If you change a Map, you get a new one, thus you get a > > new > > >>>> tree containing the new Map. > > >>>> > > >>>> > > > >>>> > But that trick isn't always available. In the example we are > > talking > > >>>> > about we can't make a Map where they keys are the instance variable > > >>>> > names and the values are their values. That would seem to do the > > job, > > >>>> > but since the values are of different types, we can't create such a > > >>>> > Map. > > >>>> > > > >>>> > So now what? > > >>>> > > >>>> Well, what's the problem with the compiler copying some nodes? > > >>>> Normally, that doesn't cost very much performance, if it does in your > > >>>> case, > > >>>> we'd need to know more to suggest the best way to go. > > >>>> > > >>>> > * > > >>>> > -- Russ * > > >>>> > > > >>> > > >> > > > > > > > > > _______________________________________________ > > > Beginners mailing list > > > Beginners@haskell.org > > > http://www.haskell.org/mailman/listinfo/beginners > > > > > > > > > > > > > > -- > > ===================== > > Patrick LeBoutillier > > Rosemère, Québec, Canada > > > _______________________________________________ > Beginners mailing list > Beginners@haskell.org > http://www.haskell.org/mailman/listinfo/beginners ------------------------------ Message: 3 Date: Fri, 26 Nov 2010 08:20:38 +0100 From: Jan Snajder <jan.snaj...@fer.hr> Subject: [Haskell-beginners] Random computation with fixed seed value (Control.Monad.Random) To: beginners@haskell.org Message-ID: <1290756038.1868.13.ca...@arjuna> Content-Type: text/plain; charset="UTF-8" Hi, I'd like to evaluate a random computation using Control.Monad.Random, but I'd like to be able to fix the seed value. I know I can use mkStdGen from System.Random to get an initial generator. I also know I can use evalRand :: RandomGen g => Rand g a -> g -> a from Control.Monad.Random to evaluate a random computation. But the problem is I don't see how I can turn a StdGen value that I get from mkStdGen into a Rand type. What am I missing here? Best, Jan ------------------------------ Message: 4 Date: Fri, 26 Nov 2010 12:16:14 +0100 From: Daniel Fischer <daniel.is.fisc...@web.de> Subject: Re: [Haskell-beginners] Random computation with fixed seed value (Control.Monad.Random) To: beginners@haskell.org, jan.snaj...@fer.hr Message-ID: <201011261216.15170.daniel.is.fisc...@web.de> Content-Type: text/plain; charset="utf-8" On Friday 26 November 2010 08:20:38, Jan Snajder wrote: > Hi, > > I'd like to evaluate a random computation using Control.Monad.Random, > but I'd like to be able to fix the seed value. I know I can use mkStdGen > from System.Random to get an initial generator. I also know I can use > > evalRand :: RandomGen g => Rand g a -> g -> a > > from Control.Monad.Random to evaluate a random computation. But the > problem is I don't see how I can turn a StdGen value that I get from > mkStdGen into a Rand type. What would you need that for? Rand is basically the State monad (newtype wrapped), which is basically s -> (a,s) (newtype wrapped). You can write your computation so that it works with whatever pseudo-random generator it is given and then let g be determined by the value passed to evalRand. That is the default use case. For example die :: (RandomGen g) => Rand g Int die = getRandomR (1,6) dice :: (RandomGen g) => Int -> Rand g [Int] dice n = sequence (replicate n die) main :: IO () main = do print $ evalRand (dice 10) (mkStdGen 123) print $ evalRand (dice 10) (mkBlumBlumShub 2379009 1234567890983) (for a hypothetical data BlumBlumShub = BBS !Integer !Integer instance RandomGen BlumBlumShub where ... mkBlumBlumShub :: Integer -> Integer -> BlumBlumShub ) > What am I missing here? > > Best, > Jan > ------------------------------ Message: 5 Date: Fri, 26 Nov 2010 12:51:11 +0100 From: Jan Snajder <jan.snaj...@fer.hr> Subject: Re: [Haskell-beginners] Random computation with fixed seed value (Control.Monad.Random) To: Daniel Fischer <daniel.is.fisc...@web.de>, beginners <beginners@haskell.org> Message-ID: <1290772271.1945.21.ca...@arjuna> Content-Type: text/plain; charset="UTF-8" Daniel, On Fri, 2010-11-26 at 12:16 +0100, Daniel Fischer wrote: > On Friday 26 November 2010 08:20:38, Jan Snajder wrote: > > Hi, > > > > I'd like to evaluate a random computation using Control.Monad.Random, > > but I'd like to be able to fix the seed value. I know I can use mkStdGen > > from System.Random to get an initial generator. I also know I can use > > > > evalRand :: RandomGen g => Rand g a -> g -> a > > > > from Control.Monad.Random to evaluate a random computation. But the > > problem is I don't see how I can turn a StdGen value that I get from > > mkStdGen into a Rand type. > > What would you need that for? Solely for illustrative purposes. I need to compare a result of a random computation when I run it with different parameters. > Rand is basically the State monad (newtype wrapped), which is basically > > s -> (a,s) > > (newtype wrapped). > > You can write your computation so that it works with whatever pseudo-random > generator it is given and then let g be determined by the value passed to > evalRand. That is the default use case. > > For example > > die :: (RandomGen g) => Rand g Int > die = getRandomR (1,6) > > dice :: (RandomGen g) => Int -> Rand g [Int] > dice n = sequence (replicate n die) > > main :: IO () > main = do > print $ evalRand (dice 10) (mkStdGen 123) > print $ evalRand (dice 10) (mkBlumBlumShub 2379009 1234567890983) > > (for a hypothetical > > data BlumBlumShub = BBS !Integer !Integer > > instance RandomGen BlumBlumShub where ... > > mkBlumBlumShub :: Integer -> Integer -> BlumBlumShub > ) Great, thanks! I tried the other way around: evalRand (mkStdGen 123) (dice 10) and kept scratching my head wondering why it doesn't work. :-) I guess it was too early in the morning. Best, Jan ------------------------------ _______________________________________________ Beginners mailing list Beginners@haskell.org http://www.haskell.org/mailman/listinfo/beginners End of Beginners Digest, Vol 29, Issue 41 *****************************************