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. Re: unit tests (John Dorsey)
2. Re: some insights into functional programming (John Dorsey)
3. Re: unit tests (Thomas Davie)
4. Re: some insights into functional programming (Adam Bergmark)
5. Re: some insights into functional programming (Michael P Mossey)
6. creating a complement for a given given test generator.
(Srikanth K)
7. brief example of ZipList? (Michael P Mossey)
8. Re: brief example of ZipList? (Antoine Latter)
----------------------------------------------------------------------
Message: 1
Date: Sun, 9 Aug 2009 17:52:23 -0400
From: John Dorsey <[email protected]>
Subject: Re: [Haskell-beginners] unit tests
To: [email protected]
Message-ID: <[email protected]>
Content-Type: text/plain; charset=us-ascii
Michael,
> As I write Haskell code I find myself needing to write test code. If this
> test code were organized and documented, I could probably call it a set of
> unit tests. I'm trying to find some convention for naming functions and
> variables used in unit testing, deciding on location (in same module or a
> second module? same directory or sub-directory?), etc. Are there any
> Haskell community conventions?
quickcheck at least has the convention of calling testable properties by
names starting with 'prop_'. I think it's common to include them within a
package, but they're generally not compiled and run by default. Cabal has a
way to hook your tests in so that 'cabal test <package>' does the right
thing, but I don't remember, and my cabal fu isn't very strong.
I don't think there's any consensus on where within your package to put
them; you could put them in a test/ directory, or do anything that makes
sense within your project.
John
------------------------------
Message: 2
Date: Sun, 9 Aug 2009 18:05:21 -0400
From: John Dorsey <[email protected]>
Subject: Re: [Haskell-beginners] some insights into functional
programming
To: [email protected]
Message-ID: <[email protected]>
Content-Type: text/plain; charset=us-ascii
Michael,
> g mx my = mx >>= (\x -> my >>= \y -> W (x+y))
>
> There are a couple things here that threw me off. One is that I didn't
> expect 'my' to be available inside the first lambda. I somehow thought of
> lambda as isolated, sealed-off from the rest of the universe. But they
> aren't. I believe this is the concept of closures, or related to it?
Yes! You're spot on; 'my' is available precisely because closures
encapsulate the part of the surrounding environment that's referenced by
bound variables.
> Secondly, I didn't expect >>= to be available inside the lambda. This is
> related to the mistaken conception of >>= as a procedural statement
> rather than an expression. In Python, where I have previously encountered
> lambdas, no statements are allowed inside lambdas. Of course, >>= is
> actually an expression and you can put any expression to the right of a
> lambda ->.
With all due respect to Python (a language I like but no longer use), it's
no place to develop any intuition about lambdas.
Python's lambda is an attempt to incorporate some of the syntactic benefit
of anonymous functions while refusing them any real meaning or importance.
> Maybe these are typical beginner misconceptions, or maybe they have more
> to do with coming from Python and complete beginners actually find it
> more natural.
As you can probably guess, I think it's more the latter. But I can't say
first-hand because I dabbled in dozens of languages before Haskell, and I
got my intuition for lambda from scheme. I wish I'd learned them in Haskell
though, because with purity they're more elegant.
Cheers,
John
------------------------------
Message: 3
Date: Mon, 10 Aug 2009 01:52:49 +0200
From: Thomas Davie <[email protected]>
Subject: Re: [Haskell-beginners] unit tests
To: "Michael Mossey" <[email protected]>
Cc: [email protected]
Message-ID: <[email protected]>
Content-Type: text/plain; charset=US-ASCII; format=flowed; delsp=yes
On 9 Aug 2009, at 22:52, Michael Mossey wrote:
> As I write Haskell code I find myself needing to write test code. If
> this
> test code were organized and documented, I could probably call it a
> set of
> unit tests. I'm trying to find some convention for naming functions
> and
> variables used in unit testing, deciding on location (in same module
> or a
> second module? same directory or sub-directory?), etc. Are there any
> Haskell community conventions?
Take a look at both QuickCheck and HUnit.
Bob
------------------------------
Message: 4
Date: Mon, 10 Aug 2009 03:07:44 +0200
From: Adam Bergmark <[email protected]>
Subject: Re: [Haskell-beginners] some insights into functional
programming
To: [email protected]
Message-ID: <[email protected]>
Content-Type: text/plain; charset=US-ASCII; format=flowed; delsp=yes
The reason my is available in the lambda \x -> my >>= \y -> W (x+y)
has to do with scoping rules, Haskell (and almost all programming
languages) use static scoping, meaning a variable defined in an outer
function is available in the inner function, for instance, (\a -> \b -
> (a,b)) 1 2 will evauate to (1,2) since a is bound to 1 in the outer
lambda, and the inner one can refer to the outer one, if instead you
write (\a -> \a -> (a,a)) 1 2 the result will be (2,2) since the
innermost a will be used (no ambiguity here, but if shadowing is done
by accident it can be hard to find the error). The book Structure and
Interpretation of Computer Programs (freely available online)
discusses this subject in detail.
>>= is available inside the lambda for the same reason, >>= is
imported into the modules namespace, and therefore available
everewhere, unless a shadowing binding exists.
I wouldn't say that this has anything to do with functional
programming specifically.
This also exists in Python i might add, you can read variables defined
in an outer scope:
>>> a = 1
>>> f()
>>> def f():
... return a
...
>>> f()
1
The fact that most languages are scoped like this is nothing obvious,
and like I said, Python is the same.
I hope this helps!
/ Adam
On Aug 9, 2009, at 9:31 PM, Michael Mossey wrote:
> I'm starting to figure out a few things that I didn't "get" about
> functional programming and monads. I wanted to explain them. I'm not
> looking for a particular response to this post, other than any
> elaboration that seems natural.
>
> There is an exercise here working with the trivial monad W:
>
> <http://blog.sigfpe.com/2007/04/trivial-monad.html>
>
> Write a function
> g :: W a -> W a -> W a
>
> such that
> g (W x) (W y) = W (x+y)
>
> except don't use pattern matching, but >>= instead. The answer is
>
> g mx my = mx >>= (\x -> my >>= \y -> W (x+y))
>
> There are a couple things here that threw me off. One is that I
> didn't expect 'my' to be available inside the first lambda. I
> somehow thought of lambda as isolated, sealed-off from the rest of
> the universe. But they aren't. I believe this is the concept of
> closures, or related to it?
>
> Secondly, I didn't expect >>= to be available inside the lambda.
> This is related to the mistaken conception of >>= as a procedural
> statement rather than an expression. In Python, where I have
> previously encountered lambdas, no statements are allowed inside
> lambdas. Of course, >>= is actually an expression and you can put
> any expression to the right of a lambda ->.
>
> Maybe these are typical beginner misconceptions, or maybe they have
> more to do with coming from Python and complete beginners actually
> find it more natural.
>
> Mike
>
> _______________________________________________
> Beginners mailing list
> [email protected]
> http://www.haskell.org/mailman/listinfo/beginners
------------------------------
Message: 5
Date: Mon, 10 Aug 2009 15:36:13 -0700
From: Michael P Mossey <[email protected]>
Subject: Re: [Haskell-beginners] some insights into functional
programming
To: beginners <[email protected]>
Message-ID: <[email protected]>
Content-Type: text/plain; charset=ISO-8859-1; format=flowed
Thanks for the ideas, Adam. I still have a few questions.
Adam Bergmark wrote:
> The reason my is available in the lambda \x -> my >>= \y -> W (x+y) has
> to do with scoping rules, Haskell (and almost all programming languages)
> use static scoping, meaning a variable defined in an outer function is
> available in the inner function, for instance, (\a -> \b -> (a,b)) 1 2
> will evauate to (1,2) since a is bound to 1 in the outer lambda, and the
> inner one can refer to the outer one, if instead you write (\a -> \a ->
> (a,a)) 1 2 the result will be (2,2) since the innermost a will be used
> (no ambiguity here, but if shadowing is done by accident it can be hard
> to find the error).
Because the lambda is executed by the implementation of >>=, doesn't the
concept
closure still apply? That value of 'my' has to "get into" the other routine.
I am aware that other languages have closures, but in Python they are an
advanced, rarely explored concept, so I haven't gotten a good intuition for
them. (I don't mean to imply I've only programmed in Python---also Lisp and
C++,
but only to do boring things, never anything sophisticated from a CS point of
view.)
It's not that I don't understand the use of 'my'---it's just that it didn't
occur to me at first.
> The book Structure and Interpretation of Computer
> Programs (freely available online) discusses this subject in detail.
>
> >>= is available inside the lambda for the same reason, >>= is imported
> into the modules namespace, and therefore available everewhere, unless a
> shadowing binding exists.
>
The problem is not that I didn't expect >>= to be outside the namespace. The
problem is that I am still having to "unlearn" imperative concepts, so it was
all too easy to think of >>= as an imperative concept, and in Python procedural
statements are not allowed inside lambdas. Also, in the early stages of
learning
Haskell there are no monads used inside lambdas. So it's not that anyone told
me
I couldn't do it, just that it didn't occur to me the first time I saw the
problem.
There is no great revelation here, other than my own satisfaction at seeing a
little deeper into the way things are done in Haskell, and finding these
problems much easier after revisiting them (I didn't do anything Haskell for a
couple months, and just came back to it).
-Mike
------------------------------
Message: 6
Date: Tue, 11 Aug 2009 00:20:16 +0100
From: Srikanth K <[email protected]>
Subject: [Haskell-beginners] creating a complement for a given given
test generator.
To: beginners <[email protected]>
Message-ID:
<[email protected]>
Content-Type: text/plain; charset="iso-8859-1"
Hi,
I am trying to use the quickcheck to generate some test-data to test an
api, along the lines of
http://www.haskell.org/haskellwiki/QuickCheck_as_Test_Set_Generator.
For the sake of example, I choose the following function to test
data Result = Valid | Invalid
api_under_test :: (Int,Int) -> Result
api_under_test (x,y)
| (x == 1) = Valid
| otherwise = Invalid
I had the following valid-generator which worked quite easily(trivial)
validCombinations= [ (1,1), (1,2) ]
validGen = elements validCombinations
prop_valid_api_under_test =
forAll validGen $ \xs ->
(api_under_test xs) == (Valid)
Now, I want to have a complement to state:
forall tuples not in validCombinations, the api_under_test must return
"Invalid". (i.e.)
prop_invalid_api_under_test =
forAll invalidGen $ \xs ->
(api_under_test xs) == (Invalid)
However, inspite of all googling, and reading the various docs including
quickcheck, I am at loss on how I can elegantly define the "invalidGen"
generator. One possible way I can think is to have a customized generator,
that would generate two random numbers and then look up the tuple generated
against the validCombinations list.
However, I feel there just might be a better way of solving this.
Any suggestion on how I should be trying to solve this.
- Srikanth
-------------- next part --------------
An HTML attachment was scrubbed...
URL:
http://www.haskell.org/pipermail/beginners/attachments/20090810/00eb27b0/attachment-0001.html
------------------------------
Message: 7
Date: Mon, 10 Aug 2009 17:08:16 -0700
From: Michael P Mossey <[email protected]>
Subject: [Haskell-beginners] brief example of ZipList?
To: beginners <[email protected]>
Message-ID: <[email protected]>
Content-Type: text/plain; charset=ISO-8859-1; format=flowed
Can someone give me a brief example using ZipList? I want to do something like
z1 :: [Int -> Int]
z1 = [succ,succ]
z2 :: [Int]
z2 = [1,2]
z3 = z1 <*> z2
But don't know to get it to regard these as ZipLists and not regular lists.
This is purely for learning purposes. No application in mind.
-Mike
------------------------------
Message: 8
Date: Mon, 10 Aug 2009 19:55:34 -0500
From: Antoine Latter <[email protected]>
Subject: Re: [Haskell-beginners] brief example of ZipList?
To: Michael P Mossey <[email protected]>
Cc: beginners <[email protected]>
Message-ID:
<[email protected]>
Content-Type: text/plain; charset=ISO-8859-1
On Mon, Aug 10, 2009 at 7:08 PM, Michael P Mossey<[email protected]>
wrote:
> Can someone give me a brief example using ZipList? I want to do something
> like
>
> z1 :: [Int -> Int]
> z1 = [succ,succ]
>
> z2 :: [Int]
> z2 = [1,2]
>
> z3 = z1 <*> z2
>
> But don't know to get it to regard these as ZipLists and not regular lists.
>
> This is purely for learning purposes. No application in mind.
z3 = getZipList $ (ZipList z1) <*> (ZipList z2)
Should do what you want. Does that make sense?
Antoine
------------------------------
_______________________________________________
Beginners mailing list
[email protected]
http://www.haskell.org/mailman/listinfo/beginners
End of Beginners Digest, Vol 14, Issue 6
****************************************