Send Beginners mailing list submissions to
[email protected]
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
[email protected]
You can reach the person managing the list at
[email protected]
When replying, please edit your Subject line so it is more specific
than "Re: Contents of Beginners digest..."
Today's Topics:
1. Stockholm Haskell User Group? (Obscaenvs 74)
2. some Data.Map questions (Dennis Raddle)
3. Where/Let clauses and subexpression repetition/memoization
(Michael Serra)
4. Re: Where/Let clauses and subexpression
repetition/memoization (Brandon Allbery)
5. Re: some Data.Map questions (David McBride)
6. Re: some Data.Map questions (Dennis Raddle)
7. Fwd: Simple help with structuring a program (Matt Williams)
8. Re: Where/Let clauses and subexpression
repetition/memoization (Daniel Fischer)
----------------------------------------------------------------------
Message: 1
Date: Thu, 18 Aug 2011 18:54:37 +0200
From: Obscaenvs 74 <[email protected]>
Subject: [Haskell-beginners] Stockholm Haskell User Group?
To: [email protected]
Message-ID:
<CA+jTTE=vwh4vnanrymt9w1na4tbu7jytvswnky55lvw97jm...@mail.gmail.com>
Content-Type: text/plain; charset=ISO-8859-1
I am posting this again although it might be the wrong forum to do so:
I feel there is definitely a need for a Haskell User Group in
Stockholm. If you are interested, contact me: [email protected] . My
name is Fredrik.
/F
------------------------------
Message: 2
Date: Thu, 18 Aug 2011 17:57:33 -0700
From: Dennis Raddle <[email protected]>
Subject: [Haskell-beginners] some Data.Map questions
To: Haskell Beginners <[email protected]>
Message-ID:
<cakxlvoojvbgdizkxk7ggv9by1junqbikiwblb7ovtlzckqf...@mail.gmail.com>
Content-Type: text/plain; charset=ISO-8859-1
Here's my problem. It's from music. I have a program which reads a
MusicXML file and creates a realization (performance) via software
synthesis. Currently I'm working on pizzicato and arco markings. Let
me explain. A string instrument can play in a number of ways. To name
two of them, in "pizzicato" playing, the musician plucks a string,
while in "arco" the musician bows the string. Pizzicato and arco
markings appear above notes in the sheet music. (Therefore they appear
in the MusicXML which is a representation of sheet music.) If a piece
has no marking at all, or no marking until later in the piece, "arco"
is assumed. When a "pizz." (the usual abbreviation as it appears in
sheet music) occurs, then the note under the marking should be played
pizzicato, and *so should all following notes until another marking.*
When an "arco" occurs, likewise that note and all following notes
until the next marking should be played arco.
The goal is to determine, for every note in the score, how it should be played.
Here's some of the code I have.
data Loc = <... representation of a location (measure # and beat) in
the score ..>
data Note = <.. all data describing a note in the score ... >
-- this structure holds all notes. there can be one or many notes at
each location
notes :: Map Loc [Note]
-- pizz. and arco are called, in MusicXML terms, a <direction> of type <words>
-- They are only two of many such words.
data DirectionWords = DirectionWords String
-- this structure holds all direction-words in the score
directionWords :: Map Loc [DirectionWords]
The following code is not a complete solution, but it illustrates the
lovely mapAccum function in Data.Map.
Suppose we have
data PlayDirection = PlayPizz
| PlayArco
To determine the direction in effect at each location in
'directionWords' (not in 'notes' which is what we really want) we can
use mapAccum in Data.Map.
directionInEffect :: Map Loc PlayDirection
directionInEffect = snd $ mapAccum step PlayArco directionWords
where
step :: PlayDirection -> [DirectionWords] -> (PlayDirection,PlayDirection)
step dir words
| any (== DirectionWords "arco") words = (PlayArco, PlayArco)
| any (== DirectionWords "pizz.") words = (PlayPizz, PlayPizz)
| otherwise = (dir, dir)
But what I really need to do is determine the direction in effect at
each location in 'notes'
------------------------------
Message: 3
Date: Thu, 18 Aug 2011 20:21:01 -0500
From: Michael Serra <[email protected]>
Subject: [Haskell-beginners] Where/Let clauses and subexpression
repetition/memoization
To: [email protected]
Message-ID:
<CADN_yYT4Z1kX90H-kTgzshaq3NT0su2BpSJzF1FKYc=w2gs...@mail.gmail.com>
Content-Type: text/plain; charset="iso-8859-1"
Dear Haskell Community,
I have been bedeviled by a persistent confusion about one aspect of
where/let clauses, which I think I can illustrate more easily with code than
with words. Given code like this:
averageR pxls = map (pcast . setR ravg) pxls'
where (ravg,_,_) = averages pxls'
pxls' = map pcast pxls
What happens if I substitute pxls' for its right-hand side,
averageR pxls = map (pcast . setR ravg) (map pcast pxls)
where (ravg,_,_) = averages (map pcast pxls)
My "superstition" here has been that the former only evaluates pxls' once,
whereas the latter computes it twice. This seems like a basic issue which
must have been confirmed or debunked somewhere in my readings, but it hasn't
sunk in with me.
-------------- next part --------------
An HTML attachment was scrubbed...
URL:
<http://www.haskell.org/pipermail/beginners/attachments/20110818/b1957c3c/attachment-0001.htm>
------------------------------
Message: 4
Date: Thu, 18 Aug 2011 22:22:22 -0400
From: Brandon Allbery <[email protected]>
Subject: Re: [Haskell-beginners] Where/Let clauses and subexpression
repetition/memoization
To: Michael Serra <[email protected]>
Cc: [email protected]
Message-ID:
<CAKFCL4XjfBiyFUnyG9jYu0Oz0wmWTKwxuNaTSfqWiw1Jpqn_=w...@mail.gmail.com>
Content-Type: text/plain; charset="utf-8"
On Thu, Aug 18, 2011 at 21:21, Michael Serra <[email protected]> wrote:
> My "superstition" here has been that the former only evaluates pxls' once,
> whereas the latter computes it twice. This seems like a basic issue which
> must have been confirmed or debunked somewhere in my readings, but it hasn't
> sunk in with me.
>
As I understand it, common subexpression elimination in lazy languages is
difficult at best because the shared subexpressions may thereby become
ineligible for fusion, so you're expected to do it explicitly by means of
where/let clauses. So your superstition is actually the truth.
--
brandon s allbery [email protected]
wandering unix systems administrator (available) (412) 475-9364 vm/sms
-------------- next part --------------
An HTML attachment was scrubbed...
URL:
<http://www.haskell.org/pipermail/beginners/attachments/20110818/e282065a/attachment-0001.htm>
------------------------------
Message: 5
Date: Thu, 18 Aug 2011 23:46:29 -0400
From: David McBride <[email protected]>
Subject: Re: [Haskell-beginners] some Data.Map questions
To: Dennis Raddle <[email protected]>
Cc: Haskell Beginners <[email protected]>
Message-ID:
<CAN+Tr42YxtUg=H898Bu=uGsn02s07cyQgYFPUB7oWY=qfc6...@mail.gmail.com>
Content-Type: text/plain; charset=ISO-8859-1
Maybe something like this:
instance Eq Loc where
a == b = ...
instance Ord Loc where
compare a b = ...
data Instruction = InstrNote (Loc, Note) | InstrPD (Loc, PlayDirection)
write a function that will combine the notes and playdirections into
one list of everything sequentially.
combineNotesDirs :: [(Loc,Note)] -> [(Loc,PlayDirection)] -> [Instruction]
combineNotesDirs [] [] = []
combineNotesDirs [] (d:ds) = undefined --you can figure this out
combineNotesDirs (n:ns) [] = undefined
combineNotesDirs notes@(n:ns) dirs@(d:ds)
| fst d <= fst n = InstrPD d : (zipNotesDirs notes ds)
| otherwise = InstrNote n : (zipNotesDirs ns dirs)
Then loop over that and store them as a map. Traverse the list, keep
track of the playdirection at each entry, and then accumulate the
current direction and note at each note entry into a new map.
instructionlist2map :: [Instruction] -> Map Loc (Note, PlayDirection)
I'm sure this could be cleaned up a bit, but is that sort of what you
were looking for?
On Thu, Aug 18, 2011 at 8:57 PM, Dennis Raddle <[email protected]> wrote:
> Here's my problem. It's from music. I have a program which reads a
> MusicXML file and creates a realization (performance) via software
> synthesis. Currently I'm working on pizzicato and arco markings. Let
> me explain. A string instrument can play in a number of ways. To name
> two of them, in "pizzicato" playing, the musician plucks a string,
> while in "arco" the musician bows the string. Pizzicato and arco
> markings appear above notes in the sheet music. (Therefore they appear
> in the MusicXML which is a representation of sheet music.) If a piece
> has no marking at all, or no marking until later in the piece, "arco"
> is assumed. When a "pizz." (the usual abbreviation as it appears in
> sheet music) occurs, then the note under the marking should be played
> pizzicato, and *so should all following notes until another marking.*
> When an "arco" occurs, likewise that note and all following notes
> until the next marking should be played arco.
>
> The goal is to determine, for every note in the score, how it should be
> played.
>
> Here's some of the code I have.
>
> data Loc = <... representation of a location (measure # and beat) in
> the score ..>
>
> data Note = <.. all data describing a note in the score ... >
>
> -- this structure holds all notes. there can be one or many notes at
> each location
> notes :: Map Loc [Note]
>
> -- pizz. and arco are called, in MusicXML terms, a <direction> of type <words>
> -- They are only two of many such words.
> data DirectionWords = DirectionWords String
>
> -- this structure holds all direction-words in the score
> directionWords :: Map Loc [DirectionWords]
>
> The following code is not a complete solution, but it illustrates the
> lovely mapAccum function in Data.Map.
>
> Suppose we have
>
> data PlayDirection = PlayPizz
> ? ? ? ? ? ? ? ? ? ? ? ? ? | PlayArco
>
> To determine the direction in effect at each location in
> 'directionWords' (not in 'notes' which is what we really want) we can
> use mapAccum in Data.Map.
>
>
> directionInEffect :: Map Loc PlayDirection
> directionInEffect = snd $ mapAccum step PlayArco directionWords
> ?where
> ? ?step :: PlayDirection -> [DirectionWords] -> (PlayDirection,PlayDirection)
> ? ?step dir words
> ? ? ?| any (== DirectionWords "arco") words = (PlayArco, PlayArco)
> ? ? ?| any (== DirectionWords "pizz.") words = (PlayPizz, PlayPizz)
> ? ? ?| otherwise = (dir, dir)
>
>
> But what I really need to do is determine the direction in effect at
> each location in 'notes'
>
> _______________________________________________
> Beginners mailing list
> [email protected]
> http://www.haskell.org/mailman/listinfo/beginners
>
------------------------------
Message: 6
Date: Thu, 18 Aug 2011 23:40:21 -0700
From: Dennis Raddle <[email protected]>
Subject: Re: [Haskell-beginners] some Data.Map questions
To: David McBride <[email protected]>
Cc: Haskell Beginners <[email protected]>
Message-ID:
<CAKxLvorPM1xfyXiW0xjjz6Vs24tE0b0Or1AmsD1SBo7kR=o...@mail.gmail.com>
Content-Type: text/plain; charset=ISO-8859-1
Hi David,
This helps, for sure. I wondered if any of the rich selection of
functions in Data.Map could be used, such as union. To perform a union
on two maps, their elements must have the same type. From this one
concludes that a type unifying Note's and PlayDirection's is
necessary, which is what you have done in Instruction.
On Thu, Aug 18, 2011 at 8:46 PM, David McBride <[email protected]> wrote:
> Maybe something like this:
>
> instance Eq Loc where
> ?a == b = ...
> instance Ord Loc where
> ?compare a b = ...
>
> data Instruction = InstrNote (Loc, Note) | InstrPD (Loc, PlayDirection)
>
> write a function that will combine the notes and playdirections into
> one list of everything sequentially.
>
> combineNotesDirs :: [(Loc,Note)] -> [(Loc,PlayDirection)] -> [Instruction]
> combineNotesDirs [] [] = []
> combineNotesDirs [] (d:ds) = undefined --you can figure this out
> combineNotesDirs (n:ns) [] = undefined
> combineNotesDirs notes@(n:ns) dirs@(d:ds)
> ?| fst d <= fst n = InstrPD d : (zipNotesDirs notes ds)
> ?| otherwise ? ? ?= InstrNote n : (zipNotesDirs ns dirs)
>
> Then loop over that and store them as a map. ?Traverse the list, keep
> track of the playdirection at each entry, and then accumulate the
> current direction and note at each note entry into a new map.
>
> instructionlist2map :: [Instruction] -> Map Loc (Note, PlayDirection)
>
> I'm sure this could be cleaned up a bit, but is that sort of what you
> were looking for?
>
------------------------------
Message: 7
Date: Fri, 19 Aug 2011 08:20:37 +0100
From: Matt Williams <[email protected]>
Subject: [Haskell-beginners] Fwd: Simple help with structuring a
program
To: [email protected]
Message-ID: <[email protected]>
Content-Type: text/plain; charset=ISO-8859-1; format=flowed
Dear All,
Apologies for the very basic question. I have some familiarity with
programming (Java/ Python), and have started learning Haskell (Real
World Haskell, Haskell 98 Tutorial, YAHT). I think I know how to
translate ideas in the real world into OOP approaches (Objects,
Inheritance, Polymorphism, Patterns).
I am having some problems trying to do this with Haskell. Should I think
about types as being a useful way to structure things, with functions
operating on them? Could anyone (very simply) explain the difference
between a type and an object class (or point me to someone who has
already done so).
Is there an equivalent of the GoF design patterns for Haskell?
Thanks and apologies for what are very basic questions,
Matt
------------------------------
Message: 8
Date: Fri, 19 Aug 2011 11:52:09 +0200
From: Daniel Fischer <[email protected]>
Subject: Re: [Haskell-beginners] Where/Let clauses and subexpression
repetition/memoization
To: [email protected]
Message-ID: <[email protected]>
Content-Type: Text/Plain; charset="utf-8"
On Friday 19 August 2011, 04:22:22, Brandon Allbery wrote:
> On Thu, Aug 18, 2011 at 21:21, Michael Serra <[email protected]> wrote:
> > My "superstition" here has been that the former only evaluates pxls'
> > once, whereas the latter computes it twice. This seems like a basic
> > issue which must have been confirmed or debunked somewhere in my
> > readings, but it hasn't sunk in with me.
>
> As I understand it, common subexpression elimination in lazy languages
> is difficult at best because the shared subexpressions may thereby
> become ineligible for fusion, so you're expected to do it explicitly by
> means of where/let clauses. So your superstition is actually the
> truth.
With a small grain of salt or two.
The language allows both, sharing and recomputation, in both cases.
But an implementation that did not share if the value is bound to a name in
a where/let would grossly violate the users' expectations, so per principle
of least surprise you can pretty much rely on sharing in the first case.
The latter is harder to predict. In most cases, you'll get recomputation,
but GHC does a bit of CSE, so in some cases it will compute only once and
share the result (which may be a bad thing - that's a further reason for
not doing too much CSE, sometimes sharing has catastrophic results).
------------------------------
_______________________________________________
Beginners mailing list
[email protected]
http://www.haskell.org/mailman/listinfo/beginners
End of Beginners Digest, Vol 38, Issue 34
*****************************************