How to avoid evaluating the second (undefined) argument of a Boolean AND operation?

Hi Folks, Here is my own version of the Bool datatype, and my own version of the Boolean AND: data MyBool = F | T myAND :: MyBool -> MyBool -> MyBool myAND F x = F myAND T x = x If the first argument is F then return F. I assumed that the second argument would not even bother being evaluated. I figured that I could provide an undefined value for the second argument: myAND F (1 / 0) However, that doesn't work. I get this error message: No instance for (Fractional MyBool) arising from a use of `/' Possible fix: add an instance declaration for (Fractional MyBool) In the second argument of `myAND', namely `(1 / 0)' In the expression: myAND F (1 / 0) In the definition of `t4': t4 = myAND F (1 / 0) Why does it evaluate the second argument when the answer is already known from the first argument? How can I design it so that if the answer is known from the first argument, then an undefined second argument doesn't produce an error? /Roger

Use myAND F _ = F instead of using x. On Jun 22, 2011, at 7:03 PM, Costello, Roger L. wrote:
Hi Folks,
Here is my own version of the Bool datatype, and my own version of the Boolean AND:
data MyBool = F | T
myAND :: MyBool -> MyBool -> MyBool myAND F x = F myAND T x = x
If the first argument is F then return F. I assumed that the second argument would not even bother being evaluated.
I figured that I could provide an undefined value for the second argument:
myAND F (1 / 0)
However, that doesn't work. I get this error message:
No instance for (Fractional MyBool) arising from a use of `/' Possible fix: add an instance declaration for (Fractional MyBool) In the second argument of `myAND', namely `(1 / 0)' In the expression: myAND F (1 / 0) In the definition of `t4': t4 = myAND F (1 / 0)
Why does it evaluate the second argument when the answer is already known from the first argument?
How can I design it so that if the answer is known from the first argument, then an undefined second argument doesn't produce an error?
/Roger
_______________________________________________ Beginners mailing list Beginners@haskell.org http://www.haskell.org/mailman/listinfo/beginners

On Wed, Jun 22, 2011 at 8:07 PM, Jack Henahan
Use
myAND F _ = F
instead of using x.
Actually that doesn't change anything and both definitions are the same thing. The problem here is that "type checking is not lazy" =). The second argument of myAND in "myAND F (1/0)" isn't being evaluated at all; actually your code isn't running at all. What is being reported is a type error, not a runtime error. Try one of these instead: myAND F undefined myAND F (error "foo") myAND F (let x = x in x) myAND F (unsafePerformIO $ launchMissiles) Cheers! =) -- Felipe.

You're right, of course. I totally spaced out while reading the error message. That'll teach me to reply to lists while on the phone. :/ On Jun 22, 2011, at 7:21 PM, Felipe Almeida Lessa wrote:
On Wed, Jun 22, 2011 at 8:07 PM, Jack Henahan
wrote: Use
myAND F _ = F
instead of using x.
Actually that doesn't change anything and both definitions are the same thing. The problem here is that "type checking is not lazy" =). The second argument of myAND in "myAND F (1/0)" isn't being evaluated at all; actually your code isn't running at all. What is being reported is a type error, not a runtime error. Try one of these instead:
myAND F undefined myAND F (error "foo") myAND F (let x = x in x) myAND F (unsafePerformIO $ launchMissiles)
Cheers! =)
-- Felipe.

On Wed, Jun 22, 2011 at 19:03, Costello, Roger L.
myAND :: MyBool -> MyBool -> MyBool myAND F x = F myAND T x = x
If the first argument is F then return F. I assumed that the second argument would not even bother being evaluated.
I figured that I could provide an undefined value for the second argument:
myAND F (1 / 0)
However, that doesn't work. I get this error message:
There's no evaluation here. Haskell does no implicit coercions for you (with a limited exception involving the definition of numeric literals) so you are passing a Fractional a => a (1/0) when a MyBool is expected, and MyBool isn't a Fractional. (No coercions means, in this case, that a number *cannot* be used as a boolean, neither a real one nor your alternative formulation, without some kind of explicit coercion.) How you fix this depends on what you're trying to accomplish. If you really want to use a division by zero there, you need to use an Integral a => a and coerce it manually:
myAND F (toEnum (1 `div` 0))
or, if you insist on Fractional,
myAND F (toEnum (fromRational (1 / 0)))
...and both of these require that you declare MyBool as
data MyBool = F | T deriving Enum
so that you can use toEnum. If you're just trying to prove the point about lazy evaluation, leave the numbers out of it:
myAND F undefined
("undefined"'s type is "a", that is, any type; from this you can infer that it can never produce an actual value, it can only raise an exception, because there is no value that inhabits all possible types.) Alternately you can say
myAND F (error "wait, what?")
which lets you control what message is printed if for some reason the second parameter is evaluated. -- brandon s allbery allbery.b@gmail.com wandering unix systems administrator (available) (412) 475-9364 vm/sms
participants (4)
-
Brandon Allbery
-
Costello, Roger L.
-
Felipe Almeida Lessa
-
Jack Henahan