if I try > fst(a, b)
where a
, b
are undefined, I get the error that b
is undefined. Even on trying snd(a, b)
it is b
that causes the error first. I have a background in imperative programming. I am wondering if this is some kind of laziness that I don't understand.
-
4I am a bit confused. Did you typed `fst (a,b)` without defining either `a` or `b` before or did you typed something like `fst (undefined, undefined)` (`undefined` is a special variable that is throws an exception upon evaluation)? In Haskell, anything must be defined when you are using it. Haskell is no scripting language. The compiler may check, whether the variables are existant in an arbitrary order. – fuz Jun 25 '11 at 16:53
-
@FUZxxl, I typed fst (a, b) without defining either. I was doing the YAHT tutorial, where I am required to try out fst ('a', 'b'). I made a mistake. But what stuck me as odd is the order in which the variables were evaluated by the compiler. If it is arbitrary, then it is clear why I got the exception. – schatten Jun 27 '11 at 06:33
-
The variables aren't evaluated just yet, the compiler is trying to parse and then make sense of what you've written. This process is in no way lazy. – yatima2975 Jun 27 '11 at 10:59
3 Answers
I think FUZxxl's comment is absolutely correct. When I type into Hugs' repl:
Hugs> fst(a,b)
ERROR - Undefined variable "b"
Hugs> snd(a,b)
ERROR - Undefined variable "b"
This isn't a lazy/eager evaluation thing -- when Hugs checks to make sure that fst(a,b)
is valid Haskell code, it notices that a
and b
aren't defined. Those two letters don't have special meanings in Haskell, they're variables like in any other language!
It's like in Java going:
System.out.println(a);
And never saying what a
is! You'd instead write something like:
String a = "Hello world."
System.out.println(a);
To remedy this, you can either define a
and b
in a let statement, like:
>let (a,b) = (1,2) in fst(a,b)
or
>let tup = (1,2) in fst tup
or
>let a=1;b=2 in fst(a,b)
or a where statement
>fst(a,b) where a=1;b=2
etc.
Alternatively, define in some file called whatever (for example, "TestTuple.hs")
a = 1
b = 2
and in Hugs, go:
>:load TestTuple.hs
>fst(a,b)
1
Although you note that you are using Hugs, just for reference, in GHCi, you can also define variables in the REPL like this:
>let a = 1
>let b = 2
>fst(a,b)
1
>snd(a,b)
2
Here's what you will see:
Prelude> fst (undefined, undefined)
*** Exception: Prelude.undefined
Prelude> snd (undefined, undefined)
*** Exception: Prelude.undefined
As you can see, accessing an undefined element evaluates to an undefined value.
Laziness allows us to avoid evaluating the entire structure, however,
Prelude> snd (undefined, 2)
2
Your comment suggests you might have forgotten to declare some specific variables, a
and b
.

- 137,316
- 36
- 365
- 468
-
@Zach, I guess I wasn't clear enough. Here is the thing. I am expecting errors since a and b are undefined. However, the compiler, while checking for the existence of a and b, should have first told me that a is undefined. ( I entered a as the first element in the pair ). I am expecting errors. What threw me off was the order in which the variables were evaluated. Thanks for the prompt replies. – schatten Jun 27 '11 at 06:38
I think your question was why is it complaining about b but not a, and that is because haskell evaluates arguments arbitrarily. That is, you never know which one is evaluated first. In your case, apparently, haskell evaluated b before a by chance and that's why it complains about b but not a.

- 330
- 3
- 14