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.  Pointfree expeiments (Paul Sargent)
   2. Re:  Question about data structures (Russ Abbott)
   3. Re:  Question about data structures (Russ Abbott)


----------------------------------------------------------------------

Message: 1
Date: Thu, 25 Nov 2010 01:44:43 +0000
From: Paul Sargent <psa...@gmail.com>
Subject: [Haskell-beginners] Pointfree expeiments
To: beginners@haskell.org
Message-ID: <11103ef8-0607-49e4-9792-9d68ea274...@gmail.com>
Content-Type: text/plain; charset=us-ascii

I'd been playing with pointfree, looking at what certain patterns transformed 
into, and I came across this:

   pa...@mudskipper> pointfree -v "\x -> x + x"                                 
 ~
   Transformed to pointfree style:
   ap (+) id
   Optimized expression:
   ap (+) id
   join (+)

Basically I wanted to see what happened when you used a parameter multiple 
times within a function.

Intrigued by this, I did the following:

   Prelude Control.Monad> :t ap (+) id
   ap (+) id :: (Num a, Monad ((->) a)) => a -> a

I'm aware that 'ap' is related the liftM, but what is this monad, and why are 
we working in a monad at all?

...and surely this isn't the same as the original code as we now have a 
different type signature?

------------------------------

Message: 2
Date: Wed, 24 Nov 2010 17:47:34 -0800
From: Russ Abbott <russ.abb...@gmail.com>
Subject: Re: [Haskell-beginners] Question about data structures
To: matthew coolbeth <mac01...@engr.uconn.edu>
Cc: beginners@haskell.org
Message-ID:
        <aanlkti=dsgic9nznas6cn+d-sguf6ljojtbt2tcq5...@mail.gmail.com>
Content-Type: text/plain; charset="iso-8859-1"

Here's a simple example that arises in the KenKen problem.

Let's assume that instead of keeping for each cage the Operation and target
number we pre-compute all the combinations of values that will satisfy the
cage.  For example, assume that in a 4x4 game, we have a cage that refers to
cells C1 and C2 and that the cage requires those two cells to produce a
value of 2 using division, Pre-computing the possibilities, we store [(1,
2), (2, 1), (2, 4), (4, 2)] in this cage.

The cage points to the two cells it constrains, and each cell points to the
cage that constrains it.

When a cell (say C1) gets a value of (say) 2, we want to change the cage to
be [(2, 1), (2, 4)]. But when that happens, it's necessary to change cell C2
to point to the new cage -- and of course since the cell was changed the
construct that held that cell has to be changed also.

It's a bit of a pain to write the code to do all that.  This isn't to say
that the code will take that long to run or that it will use excessive
memory -- only that it feels like one is being forced to write code that one
shouldn't have to write.
*
-- Russ *



On Wed, Nov 24, 2010 at 3:11 PM, Russ Abbott <russ.abb...@gmail.com> wrote:

> Thanks, I'm still struggling with it. But here is what it looks like now.
>
> I'm working on a KenKen solver. One issue I'm having is that I'm not sure
> how many types to declare -- where by types I mean a "type X = ..."
> declaration.  The more there are the better documented the code, but the
> more there are the harder it seems to be to remember what they all are.
>  I've pasted the current version of my declarations below.  By way of
> explanation, here's the representation strategy.
>
> The puzzle board is called a Grid. It consists primarily of a Map CellRef
> Cells. I'm using a Map instead of an array (list of lists) as a way to avoid
> rebuilding the list of lists of cells when a Cell gets a value.  A CellRef
> is (Int, Int) for row and column. A Cell contains its own CellRef along with
> a reference to the Cage that refers to it. It also has a place to put its
> actual value, an Int (called type CellValue).  (In the current version a
> Cell has one value. In a subsequent version it will be more like a
> FiniteDomain variable with a Set of still possible values.)
>
> A Grid also contains two other Maps. Each is of the type Map Int ValueSet.
> One of them represents the unused values for the rows; the other the unused
> values for the columns. A ValueSet is a Set of allowable values. If the
> puzzle is (size x size), its ValueSet will be Set.fromList [1 .. size].
>
> The other main structure is the puzzle presentation, which is called a
> KenKen. It is a list of Cages, where a Cage is: a target value (what the
> operation on the cells has to come out to), an Op (the Operation to be
> performed), and a list of CellRef (which are (row, col) references to
> Cells).
>
> When I give a Cell a value, I am forced to rebuild: the Map of row
> ValueSets, the Map of column ValueSets, the Map of Cells themselves, and the
> Grid that contains all these pieces. In this case, the pieces do change.
> (The cell changes since it gets a value; the candidates still left for the
> row and column also change since that value is no longer available.) But
> still it's a pain rebuilding it all.
>
> So perhaps the first question is whether there is a cleaner and simpler way
> to represent all this.
>
>
>
> type CellValueList = [CellValue]
>
> type CellRef   = (Int, Int)
>
> type CellValue = Int
>
> data Grid      = Grid { rowCandidatesSets :: CandidatesSets
>                              , colCandidatesSets :: CandidatesSets
>                              , gridCells :: (Map CellRef Cell)
>                              }
>
> type KenKen    = [Cage]
>
> type ValueSet  = Set CellValue
>
> type CandidatesSets = Map Int ValueSet
>
> data Cell      = Cell { cellRef :: CellRef
>                            , cage:: Cage
>                            , value:: CellValue
>                            } deriving (Eq, Show)
>
> row cell = fst (cellRef cell)
> col cell = snd (cellRef cell)
>
>
> data Cage      = Cage {target :: CellValue
>                                , op :: Op
>                                , cageCells :: [CellRef]
>                                } deriving (Eq, Show)
>
> data Op        = Add | Subtract | Multiply | Divide deriving (Show, Eq)
>
>
>
> *
> -- Russ *
>
>
>
> On Wed, Nov 24, 2010 at 2:19 PM, matthew coolbeth <mac01...@engr.uconn.edu
> > wrote:
>
>> May we see a code sample of what you're describing?
>>
>> Generally, when you're writing haskell programs, you will not approach
>> the problem in the same way that you would appoach it in a language
>> with mutable objects.
>>
>> If you can provide a reasonably simple example of a computing task
>> that someone would want to perform,  I'm sure someone will be able to
>> show you how it would be best approached in haskell, and how you need
>> not write too many lines of code, provided that you use the proper,
>> idiomatic style.
>>
>> On 2010-11-24, 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 *
>> >> >
>> >>
>> >
>>
>>
>> --
>> mac
>>
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: 
http://www.haskell.org/pipermail/beginners/attachments/20101124/b27af1fb/attachment-0001.html

------------------------------

Message: 3
Date: Wed, 24 Nov 2010 17:54:50 -0800
From: Russ Abbott <russ.abb...@gmail.com>
Subject: Re: [Haskell-beginners] Question about data structures
To: Daniel Fischer <daniel.is.fisc...@web.de>
Cc: beginners@haskell.org
Message-ID:
        <aanlktinwvzrr9fbd4x6njmh1fh-qkbz2fzfn9j=be...@mail.gmail.com>
Content-Type: text/plain; charset="iso-8859-1"

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 *
>> >
>>
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: 
http://www.haskell.org/pipermail/beginners/attachments/20101124/9986e99d/attachment.html

------------------------------

_______________________________________________
Beginners mailing list
Beginners@haskell.org
http://www.haskell.org/mailman/listinfo/beginners


End of Beginners Digest, Vol 29, Issue 37
*****************************************

Reply via email to