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.  What is "~" ? (TG)
   2. Re:  What is "~" ? (Rahul Kapoor)
   3.  Re: CORRECTED: making translation from   imperative code]
      (Heinrich Apfelmus)
   4. Re:  beginner's type error (Ivan Moore)
   5. Re:  beginner's type error (John Dorsey)
   6.  Is this overkill? (Zachary Turner)
   7. Re:  Is this overkill? (Felipe Lessa)
   8.  Re: Is this overkill? (Heinrich Apfelmus)


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

Message: 1
Date: Fri, 03 Apr 2009 02:18:29 +0300
From: "TG" <[email protected]>
Subject: [Haskell-beginners] What is "~" ?
To: "Beginners Haskell" <[email protected]>
Message-ID: <[email protected]>
Content-Type: text/plain; charset="us-ascii"

Looking at the definition of "partition", it calls

    select :: (a -> Bool) -> a -> ([a], [a]) -> ([a], [a])
    select p x ~(ts,fs) | p x       = (x:ts,fs)
                        | otherwise = (ts, x:fs)

what does the "~" do? 
Can't seem to find it in the documentation, or see a difference in
output without it.
Thank you.
-- 
  TG
  [email protected]

-- 
http://www.fastmail.fm - Email service worth paying for. Try it for free



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

Message: 2
Date: Thu, 2 Apr 2009 19:21:04 -0400
From: Rahul Kapoor <[email protected]>
Subject: Re: [Haskell-beginners] What is "~" ?
To: TG <[email protected]>
Cc: Beginners Haskell <[email protected]>
Message-ID:
        <[email protected]>
Content-Type: text/plain; charset=ISO-8859-1

~ signifies a lazy pattern.

See: http://www.haskell.org/tutorial/patterns.html
for more details.

Rahul

What kind of art do you like?
http://www.artquiver.com

On Thu, Apr 2, 2009 at 7:18 PM, TG <[email protected]> wrote:
> Looking at the definition of "partition", it calls
>
>    select :: (a -> Bool) -> a -> ([a], [a]) -> ([a], [a])
>    select p x ~(ts,fs) | p x       = (x:ts,fs)
>                        | otherwise = (ts, x:fs)
>
> what does the "~" do?
> Can't seem to find it in the documentation, or see a difference in
> output without it.
> Thank you.
> --
>  TG
>  [email protected]
>
> --
> http://www.fastmail.fm - Email service worth paying for. Try it for free
>
> _______________________________________________
> Beginners mailing list
> [email protected]
> http://www.haskell.org/mailman/listinfo/beginners
>


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

Message: 3
Date: Fri, 03 Apr 2009 02:18:39 +0200
From: Heinrich Apfelmus <[email protected]>
Subject: [Haskell-beginners] Re: CORRECTED: making translation from
        imperative code]
To: [email protected]
Message-ID: <[email protected]>
Content-Type: text/plain; charset=ISO-8859-1

Michael Mossey wrote:
> Read this version.
> 
> A composition consists of several voices or instruments, each indicated
> by its own *staff*. Visually, a staff is a layout of items such as
> notes, clef signs, and accidentals arranged horizontally from left to
> right, representing increasing time.
> 
> 
> A *system* is a set of staves stacked vertically that represent
> instruments playing at the same time.
> 
> Here is a simple representation of a system, in which the pipe character
> represents items. Note that some of the items are aligned vertically
> meaning they will play at the same time. At other times, only one
> staff contains a note.
> 
> staff 1:   |    |  | |
> staff 2:     |  |    | |
> 
> Next we elaborate this model to show that items have visual width. Here
> they are represented by clusters of x's with a pipe in the middle. The pipe
> represents the part of the item that needs to be aligned with items on
> other staves. For example, in the visual representation of a chord,
> the part of the chord called the notehead needs to be aligned with
> noteheads on other staves. (A chord includes other symbols, like
> accidentals
> and flags, which get drawn to the right or left of the notehead and don't
> need to be aligned vertically with anything else.)
> 
> 
> staff 1:  x|x xx|xx        x|x
> 
> staff 2:       x|x x|x xxxxx|xxxxx
> 
>            a    b   c       d
> 
> Here you can see that there is an additional constraint on layout,
> which is that items need to have horizontal space around them so they
> don't collide. For instance, the very wide item at 'd' (on staff 2) means
> that the item on staff 1 at 'd' has to be positioned far to the right
> of its previous item.

A nice problem with an elegant solution. Let me demonstrate.

First, let's solve the simpler problem of aligning just a single staff
on unlimited paper. In other words, we are given a list of items that
extend to the left and right, and we want to calculate a position for
each one. In fact, let's dispense with items entirely and just work with
a list of extents directly.

   type Pos   = Integer
   type Width = Pos

   align :: [(Width,Width)] -> [Pos]

For instance, the item  (3,4)  corresponds to

   xxx|xxxx

Implementing this functions is straightforward

   align xs = scanl (+) a gaps
      where
      (a:as,bs) = unzip xs
      gaps      = zipWith (+) bs as

This is a very tight layout without any whitespace, but we can add some
after the fact

   addWhitespace :: Width -> [Pos] -> [Pos]
   addWhitespace margin = zipWith (+) [0,margin..]


With this, we can now align a list of events (from my previous message)
given a function that tells us their visual extents.

   alignStaff :: (a -> (Width,Width)) -> Events a -> [Pos]
   alignStaff f = align . map f


Now, what about the problem of aligning several staves on unlimited
paper? It turns out that we've already solved it! After all, we can
interpret a vertical group of items as a compound item whose total width
is just the maximum width of its components.

   alignStaves :: (a -> (Width,Width)) -> [Events a] -> [Pos]
   alignStaves f = alignStaff f' . merge
      where f' = (maximum *** maximum) . unzip . map f

In other words, we can lay out a group of staves by first merging them
in time order (as done in my previous post) and then treating the result
as a "compound" staff.


> Note that data exists in two domains: there is data that describes notes;
> that is, pitches and timbres and volumes and times and duration. We'll
> call this the 'score'. It's the fundamental data. Then there is the
> visual *representation* of the score. Here we are concerned only with
> creating a visual representation. However, we need to refer to
> data in the score.

Thanks to polymorphism, keeping this data around is no problem. The
alignStaves  function simply doesn't care what items it is going to
align, it only wants to know their widths. In fact, making  alignStave
polymorphic is key to reusing it for groups of staves.

In other words, polymorphism is key to separating concerns. You should
structure your layout engine as some kind of library that can align
anything, caring only about widths and heights. For instance, dealing
with finite paper size can be packed neatly into the  align  function.


Regards,
apfelmus

--
http://apfelmus.nfshost.com



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

Message: 4
Date: Thu, 2 Apr 2009 10:46:29 +0100
From: Ivan Moore <[email protected]>
Subject: Re: [Haskell-beginners] beginner's type error
To: Jason Dusek <[email protected]>
Cc: [email protected]
Message-ID:
        <[email protected]>
Content-Type: text/plain; charset=ISO-8859-1

without engaging my brain too much, given what you've said, then why
is "10" both integral and floating point? why not "10" being integral
and "10.0" being floating point?

On Tue, Mar 31, 2009 at 2:09 AM, Jason Dusek <[email protected]> wrote:
> 2009/03/27 Ivan Moore <[email protected]>:
>> > The reason (which is a bit confusing) is that it typechecks
>> > just fine---if there *were* a type which is an instance of
>> > both Integral and Floating (and I guess round needs RealFrac
>> > as well), n could have that type.  There isn't such a type
>> > in the standard libraries, but in theory you could make up
>> > your own type which is an instance of both.
>>
>> If there were such a type, could "10" have that type and then
>> would my problem have not existed?
>
>  Yes, that is correct.
>
>> in which case, why doesn't it!?
>
>  Does it actually make any logical sense for a type to be both
>  integral (governed by rules of modular division) and floating
>  point (governed by rules of IEEE 754 division)?
>
> --
> Jason Dusek
>


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

Message: 5
Date: Fri, 3 Apr 2009 02:33:07 -0400
From: John Dorsey <[email protected]>
Subject: Re: [Haskell-beginners] beginner's type error
To: [email protected]
Message-ID: <[email protected]>
Content-Type: text/plain; charset=us-ascii

Ivan,

> without engaging my brain too much, given what you've said, then why
> is "10" both integral and floating point? why not "10" being integral
> and "10.0" being floating point?

The literal "10", as it appears in Haskell source, stands for something
that can take on any numeric type, but as soon as you use it in a context
that constrains it, well, it gets constrained!

"10" can be integral, or it can be floating point.  As I think Jason was
saying, *if* there was a type that was both integral and floating point,
then 10 could represent something of that type.  But there's no *sensible*
type that has both integral and floating point nature.  (At least none that
comes to mind.  Maybe you could do something with symbolic manipulation
that would make sense.)

Leaving behind sensible types, we can define one that's both integral
and fractional.  I'm going to violate all kinds of commonly assumed (but
unenforced) laws of the numeric classes, in an act of self-loathing, so
enjoy the following abomination!  The code is appended at the end of
this message.

dor...@elwood:~/src/scratch$ ghci int-float.hs
*Main> :t munge
munge :: IntFloat -> IntFloat
*Main> :t munge 10
munge 10 :: IntFloat
*Main> fromIntegral (munge 10)
42

If you look at the code for munge below, you'll see that I've mixed
integral operations (div) with floating point operations (**) and
fractional operations (/).

I have no trouble applying munge to 10.  The literal "10" (which really means
"fromIntegral 10") takes on the right type because it has to to match munge's
argument type.

So why would I choose to do this terrible thing?  To illustrate that:

1) The open world assumption of Haskell type classes implies that
   a type like this could be definied later, even if it doesn't exist now.

2) Even though you can do this and obey the type rules, I had to use
   a silly type, with very silly class instance definitions.  Integral
   things just aren't fractional!

To answer you other specific question, about why they didn't just
distinguish "10" from "10.0" as some other languages do, the original
motivation was well before my time.  But it does seem to me that being
able to use "10" to refer not only to Integers and Floats, but also to
Ints, Int16s, Doubles, and many unforseen numeric types, was a clever
choice.  Sadly, numeric literals make the short-list of things that
confuse Haskell neophites the most.

I hope all this is at least either interesting or helpful.

Regards,
John


-- int-float.hs

-- a datatype inhabiting floating and integral classes,
-- but which doesn't model numerics particularly well

data IntFloat = IF String
  deriving (Show, Eq, Ord)

munge :: IntFloat -> IntFloat
munge x = x / x `div` x ** x

instance Num IntFloat where
  _ + _ = IF "sum"
  _ - _ = IF "difference"
  _ * _ = IF "product"
  negate _ = IF "negation"
  abs _ = IF "abs"
  signum _ = IF "signum"
  fromInteger _ = IF "fromInteger"

instance Integral IntFloat where
  quot _ _ = IF "quot"
  rem  _ _ = IF "rem"
  div  _ _ = IF "div"
  mod  _ _ = IF "mod"
  quotRem _ _ = (IF "quotRem quot", IF "quotRem rem")
  divMod  _ _ = (IF "divMod div", IF "divMod mod")
  toInteger _ = 42

instance Floating IntFloat where
  pi = IF "pi"
  exp _ = IF "exp"
  sqrt _ = IF "sqrt"
  log _ = IF "log"
  (**) _ _ = IF "**"
  logBase _ _ = IF "logBase"
  sin _ = IF "sin"
  tan _ = IF "tan"
  cos _ = IF "cos"
  asin _ = IF "asin"
  atan _ = IF "atan"
  acos _ = IF "acos"
  sinh _ = IF "sinh"
  tanh _ = IF "tanh"
  cosh _ = IF "cosh"
  asinh _ = IF "asinh"
  atanh _ = IF "atanh"
  acosh _ = IF "acosh"

instance Real IntFloat where
  toRational _ = toRational 42

instance Enum IntFloat where
  succ _ = IF "succ"
  pred _ = IF "pred"
  toEnum _ = IF "toEnum"
  fromEnum _ = 42
  enumFrom _ = [IF "enumFrom"]
  enumFromThen _ _ = [IF "enumFromThen"]
  enumFromTo _ _ = [IF "enumFromTo"]
  enumFromThenTo _ _ _ = [IF "enumFromThenTo"]

instance Fractional IntFloat where
  (/) _ _ = IF "/"
  recip _ = IF "recip"
  fromRational _ = IF "fromRational"



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

Message: 6
Date: Fri, 3 Apr 2009 20:58:41 -0500
From: Zachary Turner <[email protected]>
Subject: [Haskell-beginners] Is this overkill?
To: [email protected]
Message-ID:
        <[email protected]>
Content-Type: text/plain; charset="iso-8859-1"

I thought I would try to see if it were possible to write, in point-free
form using no lambda functions and no intermediate functions, a function
that takes 2 lists of Booleans, computes the pairwise logical AND of the two
lists, and returns a list containing the 0 based indices of the elements
where the logical and of the two was true.  I know that at some point it
becomes overkill and for the sake of readability one should know when to
draw the line.  So I want to see if someone with more experience than me can
comment on whether or not this is over the line :P

trueIndices = curry $ map fst . filter snd . zip [0..] . map (uncurry (&&))
. (uncurry zip)

So do all the uncurries and curries make it too hard to understand or is it
pretty easy to read this?  For me it takes me a while to figure out by
looking at it because it's hard to trace all the currying and uncurrying.
And is there a more elegant solution?
-------------- next part --------------
An HTML attachment was scrubbed...
URL: 
http://www.haskell.org/pipermail/beginners/attachments/20090403/4a7bc302/attachment-0001.htm

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

Message: 7
Date: Fri, 3 Apr 2009 23:16:30 -0300
From: Felipe Lessa <[email protected]>
Subject: Re: [Haskell-beginners] Is this overkill?
To: [email protected]
Message-ID: <[email protected]>
Content-Type: text/plain; charset=us-ascii

On Fri, Apr 03, 2009 at 08:58:41PM -0500, Zachary Turner wrote:
> trueIndices = curry $ map fst . filter snd . zip [0..] . map (uncurry (&&))
> . (uncurry zip)

Just some tips: note that

  map (uncurry f) . zip  ===  zipWith f
  curry $ f . uncurry g  ===  (f .) . g

so

  trueIndices = ((map fst . filter snd . zip [0..]) .) . zipWith (&&)

There must be some combinators to avoid the '((...) .) .' thing, though. I just 
don't remember :).

HTH,

--
Felipe.


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

Message: 8
Date: Sat, 04 Apr 2009 04:30:12 +0200
From: Heinrich Apfelmus <[email protected]>
Subject: [Haskell-beginners] Re: Is this overkill?
To: [email protected]
Message-ID: <[email protected]>
Content-Type: text/plain; charset=ISO-8859-1

Zachary Turner wrote:
> I thought I would try to see if it were possible to write, in point-free
> form using no lambda functions and no intermediate functions, a function
> that takes 2 lists of Booleans, computes the pairwise logical AND of the two
> lists, and returns a list containing the 0 based indices of the elements
> where the logical and of the two was true.  I know that at some point it
> becomes overkill and for the sake of readability one should know when to
> draw the line.  So I want to see if someone with more experience than me can
> comment on whether or not this is over the line :P
> 
> trueIndices = curry $ map fst . filter snd . zip [0..] . map (uncurry (&&))
> .. (uncurry zip)
> 
> So do all the uncurries and curries make it too hard to understand or is it
> pretty easy to read this?  For me it takes me a while to figure out by
> looking at it because it's hard to trace all the currying and uncurrying.
> And is there a more elegant solution?

Looks very readable to me, though I'd write it as

  trueIndices = (map fst . filter snd . zip [0..] .) . zipWith (&&)

or even simply as

  trueIndices xs ys =
      map fst . filter snd . zip [0..] $ zipWith (&&) xs ys

because composing functions with more than one argument tends to be a
bit messy.


With Conal's semantic editor combinators

  http://conal.net/blog/posts/semantic-editor-combinators/

it would be written as

  trueIndices =
    (result . result) (map fst . filter snd . zip [0..]) (zipWith (&&))


Regards,
apfelmus

--
http://apfelmus.nfshost.com



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

_______________________________________________
Beginners mailing list
[email protected]
http://www.haskell.org/mailman/listinfo/beginners


End of Beginners Digest, Vol 10, Issue 4
****************************************

Reply via email to