Haskell like (c:cs) syntax

S

Stefan Niemann

Hi,

sorry that I'm relatively new to Python. But the syntax and semantics of
Python already fascinate me, because I'm familiar with functional languages
like Haskell.

Is there a pattern matching construct in Python like (head : tail), meaning
'head' matches the first element of a list and 'tail' matches the rest? I
could not find this in the Python documentation.

Regards,
Stefan
 
C

Chris Mellon

Hi,

sorry that I'm relatively new to Python. But the syntax and semantics of
Python already fascinate me, because I'm familiar with functional languages
like Haskell.

Is there a pattern matching construct in Python like (head : tail), meaning
'head' matches the first element of a list and 'tail' matches the rest? I
could not find this in the Python documentation.

Regards,
Stefan

Python does not have haskell like pattern matching. Things are written
and done in a different way.

When working with lists, Python has a slice syntax (which is rather
more powerful than Haskells limited head->tail linked list syntax)
that you can use to chop a sequence up into various parts.
 
?

=?ISO-8859-1?Q?Ricardo_Ar=E1oz?=

Stefan said:
Hi,

sorry that I'm relatively new to Python. But the syntax and semantics of
Python already fascinate me, because I'm familiar with functional languages
like Haskell.

Is there a pattern matching construct in Python like (head : tail), meaning
'head' matches the first element of a list and 'tail' matches the rest? I
could not find this in the Python documentation.

Regards,
Stefan

L = ['one', 'two', 'three', 'four', 'five']

print L[0] # This would be 'head'
print L[1:] # This would be 'tail'

Caution : L[0] and L[1:] are COPIES of the head and tail of the list.
 
P

Paul Rubin

Stefan Niemann said:
Is there a pattern matching construct in Python like (head : tail), meaning
'head' matches the first element of a list and 'tail' matches the rest? I
could not find this in the Python documentation.

Python's lists are actually linear arrays. You can subscript them,
i.e. x[0] is the first element, and slice them, i.e. x[1:] is all
elements after the first. Note that x[1:] actually makes a new
array and copies all the elements of x.

Normally in Python one writes iterative loops rather than recursing
or folding over a list:

for a in x:
print a

so slicing isn't that common.

Python also has something called generators which are sort of like
Haskell's lazy-evaluation lists. They often make it possible to
program in a Haskell-like style. Note however that they are mutable
objects, i.e. using g.next() to get the next element of a generator
actually updates the generator's internal state. This can lead to a
bunch of subtle pitfalls if you're not careful, but overall they are a
very useful feature.
 
E

Erik Jones

Python does not have haskell like pattern matching. Things are written
and done in a different way.

When working with lists, Python has a slice syntax (which is rather
more powerful than Haskells limited head->tail linked list syntax)
that you can use to chop a sequence up into various parts.

That is extremely arguable (in fact, Haskell's list semantics are
extremely powerful as they are not limited to just head/tail). But,
rather than debate the merits of one language over the other, to the
OP: no, Python doesn't have any pattern matching facilities.
Binding statements must be explicit, so you could do something along
the lines of (using parallel assignment):

head, tail = l[0], l[1:]

or,

front, last = l[:len(l) - 1], l[len(l) - 1]

Erik Jones

Software Developer | Emma®
(e-mail address removed)
800.595.4401 or 615.292.5888
615.292.0777 (fax)

Emma helps organizations everywhere communicate & market in style.
Visit us online at http://www.myemma.com
 
M

Matimus

Is there a pattern matching construct in Python like (head : tail), meaning
'head' matches the first element of a list and 'tail' matches the rest? I
could not find this in the Python documentation.

Not really, but you could do something like this:

Code:
def foo(head, *tail):
    #do stuff with head and tail

foo(*seq)

Also, Python 3.0 will have `Extended Iterable Unpacking'
http://www.python.org/dev/peps/pep-3132/

This isn't quite the same as Haskell's type matching, but would enable
similar behavior in some cases.

example:
Code:
head, *tail = seq

Which would assign the first element of seq to head, and the remainder
to tail.

Matt
 
M

Marco Mariani

Ricardo Aráoz ha scritto:
L = ['one', 'two', 'three', 'four', 'five']

print L[0] # This would be 'head'
print L[1:] # This would be 'tail'

Caution : L[0] and L[1:] are COPIES of the head and tail of the list.

This might surprise people who see L[1:] = [], since changing a copy is
not supposed to change the original.
 
?

=?ISO-8859-1?Q?Ricardo_Ar=E1oz?=

Marco said:
Ricardo Aráoz ha scritto:
L = ['one', 'two', 'three', 'four', 'five']

print L[0] # This would be 'head'
print L[1:] # This would be 'tail'

Caution : L[0] and L[1:] are COPIES of the head and tail of the list.

This might surprise people who see L[1:] = [], since changing a copy is
not supposed to change the original.

Sorry, should have written RETURN copies instead of ARE copies.
 
S

Steve Holden

Istvan said:
Caution : L[0] and L[1:] are COPIES of the head and tail of the list.
Sorry, should have written RETURN copies instead of ARE copies.

L[0] does not return a copy, it does what is says, returns the object
stored at index 0.
Well, if we're going to get picky it actually returns a reference to the
object referenced by the list item indexed by 0. What was your point?

regards
Steve
--
Steve Holden +1 571 484 6266 +1 800 494 3119
Holden Web LLC/Ltd http://www.holdenweb.com
Skype: holdenweb http://del.icio.us/steve.holden
--------------- Asciimercial ------------------
Get on the web: Blog, lens and tag the Internet
Many services currently offer free registration
----------- Thank You for Reading -------------
 
S

Stefan Niemann

Thanks for all the good answers.

In fact the `Extended Iterable Unpacking' is exactly what I was looking for.
Ok, my main aspect of writing

head, *tail = seq

instead of

head, tail = seq[0], seq[1:]

is the syntactic sugar. As mentioned in the PEP this may also be faster when
iterables are involved.

Stefan

Matimus said:
Is there a pattern matching construct in Python like (head : tail),
meaning
'head' matches the first element of a list and 'tail' matches the rest? I
could not find this in the Python documentation.

Not really, but you could do something like this:

Code:
def foo(head, *tail):
#do stuff with head and tail

foo(*seq)

Also, Python 3.0 will have `Extended Iterable Unpacking'
http://www.python.org/dev/peps/pep-3132/

This isn't quite the same as Haskell's type matching, but would enable
similar behavior in some cases.

example:
Code:
head, *tail = seq

Which would assign the first element of seq to head, and the remainder
to tail.

Matt
 
E

Erik Max Francis

Marco said:
Ricardo Aráoz ha scritto:
L = ['one', 'two', 'three', 'four', 'five']

print L[0] # This would be 'head'
print L[1:] # This would be 'tail'

Caution : L[0] and L[1:] are COPIES of the head and tail of the list.

This might surprise people who see L[1:] = [], since changing a copy is
not supposed to change the original.

That's because slicing and assigning is not the same thing as slicing
alone. Slicing and assigning mutates the sequence. Slicing alone
returns a copy.
>>> L = ['one', 'two', 'three', 'four', 'five']
>>> x = L[1:] # grab a slice
>>> x[:] = [] # mutate it
>>> x []
>>> L # original list is unchanged
['one', 'two', 'three', 'four', 'five']
 
C

Carl Banks

That is extremely arguable (in fact, Haskell's list semantics are
extremely powerful as they are not limited to just head/tail).

Apples and oranges, really. Pattern matching can do an awful lot of cool
things, but arbitrary slicing isn't one of the more pleasant ones. (At
least not without a good set of slice-matching patterns handy, which I
don't know if Haskell has.)


Carl Banks
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,995
Messages
2,570,230
Members
46,819
Latest member
masterdaster

Latest Threads

Top