Is there a null statement that does nothing?

It looks like both the THEN and the ELSE in an IF expression must each have an expression. What's a graceful way to do nothing in either or both slots, kind of like the Fortran CONTINUE statement. --mr ================ [michael@localhost ~]$ ghci GHCi, version 6.10.3: http://www.haskell.org/ghc/ :? for help Loading package ghc-prim ... linking ... done. Loading package integer ... linking ... done. Loading package base ... linking ... done. Prelude> if (1==1) then else <interactive>:1:15: parse error on input `else' Prelude> if (1==1) then True else <interactive>:1:24: parse error (possibly incorrect indentation) Prelude> if (1==1) then True else False True Prelude>

If its monadic code then use Control.Monad.when.
If its pure code then omitting the 'else' clause makes no sense
what-so-ever; to omit the else you must know the boolean is always true so
why have the if? See the "Common Misunderstandings" [1] page I put together
in response to seeing one too many people trip over exactly this issue.
Thomas
[1] http://haskell.org/haskellwiki/Common_Misunderstandings
On Wed, Oct 21, 2009 at 5:43 PM, michael rice
It looks like both the THEN and the ELSE in an IF expression must each have an expression. What's a graceful way to do nothing in either or both slots, kind of like the Fortran CONTINUE statement.
--mr
================
[michael@localhost ~]$ ghci GHCi, version 6.10.3: http://www.haskell.org/ghc/ :? for help Loading package ghc-prim ... linking ... done. Loading package integer ... linking ... done. Loading package base ... linking ... done. Prelude> if (1==1) then else
<interactive>:1:15: parse error on input `else' Prelude> if (1==1) then True else
<interactive>:1:24: parse error (possibly incorrect indentation) Prelude> if (1==1) then True else False True Prelude>
_______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe

Yes, an if statement must have both 'then' and 'else' branches. As an
example, what if you had
let a = if b == 2 then True else False
and you were missing an else branch? What would 'a' get assigned to?
The if statement "returns" a value so must have both branches.
However, in a monadic constraint, there are the functions 'when' and
'unless.' They allow conditional evaluation of expressions in a monadic
context. For example,
main = do
line <- getLine
when (line == "hello") putStrLn "Hello back!"
Cheers,
- Tim
On Wed, Oct 21, 2009 at 7:43 PM, michael rice
It looks like both the THEN and the ELSE in an IF expression must each have an expression. What's a graceful way to do nothing in either or both slots, kind of like the Fortran CONTINUE statement.
--mr
================
[michael@localhost ~]$ ghci GHCi, version 6.10.3: http://www.haskell.org/ghc/ :? for help Loading package ghc-prim ... linking ... done. Loading package integer ... linking ... done. Loading package base ... linking ... done. Prelude> if (1==1) then else
<interactive>:1:15: parse error on input `else' Prelude> if (1==1) then True else
<interactive>:1:24: parse error (possibly incorrect indentation) Prelude> if (1==1) then True else False True Prelude>
_______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe

Thanks guys,
I understand what you're telling me, but have some nested IFs and just want to fall through on one of the ELSES but then I end up with two ELSES in a row and nothing between them. Oh, well, on to restructuring.
Michael
--- On Wed, 10/21/09, Tim Wawrzynczak

If you have a long if/else if/else chain, you might consider a trivial case statement with guards. Whether you think this is attractive is a matter of taste, but it has the fall-through semantics you want and ghc optimizes the _ pattern matching away: f x = case () of _| x == 2 -> 22 _| x == 4 -> 44 _| x == 7 -> 77 _| otherwise -> 55
f 4 44 f 9 55
michael rice wrote:
Thanks guys,
I understand what you're telling me, but have some nested IFs and just want to fall through on one of the ELSES but then I end up with two ELSES in a row and nothing between them. Oh, well, on to restructuring.
Michael
--- On *Wed, 10/21/09, Tim Wawrzynczak /
/* wrote: From: Tim Wawrzynczak
Subject: Re: [Haskell-cafe] Is there a null statement that does nothing? To: "michael rice" Cc: haskell-cafe@haskell.org Date: Wednesday, October 21, 2009, 8:49 PM Yes, an if statement must have both 'then' and 'else' branches. As an example, what if you had
let a = if b == 2 then True else False
and you were missing an else branch? What would 'a' get assigned to?
The if statement "returns" a value so must have both branches.
However, in a monadic constraint, there are the functions 'when' and 'unless.' They allow conditional evaluation of expressions in a monadic context. For example,
main = do line <- getLine when (line == "hello") putStrLn "Hello back!"
Cheers, - Tim
On Wed, Oct 21, 2009 at 7:43 PM, michael rice
> wrote: It looks like both the THEN and the ELSE in an IF expression must each have an expression. What's a graceful way to do nothing in either or both slots, kind of like the Fortran CONTINUE statement.
--mr
================
[michael@localhost ~]$ ghci GHCi, version 6.10.3: http://www.haskell.org/ghc/ :? for help Loading package ghc-prim ... linking ... done. Loading package integer ... linking ... done. Loading package base ... linking ... done. Prelude> if (1==1) then else
<interactive>:1:15: parse error on input `else' Prelude> if (1==1) then True else
<interactive>:1:24: parse error (possibly incorrect indentation) Prelude> if (1==1) then True else False True Prelude>
_______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe

Those nested IF/THEN/ELSEs are real killers. I kind of use them to sort out my thoughts, then end up with a nested mess. The restructuring to WHENs went smoothly and looks a lot cleaner besides.
Michael
--- On Wed, 10/21/09, Dan Weston
f 4 44 f 9 55
michael rice wrote:
Thanks guys,
I understand what you're telling me, but have some nested IFs and just want to fall through on one of the ELSES but then I end up with two ELSES in a row and nothing between them. Oh, well, on to restructuring.
Michael
--- On *Wed, 10/21/09, Tim Wawrzynczak /
/* wrote: From: Tim Wawrzynczak
Subject: Re: [Haskell-cafe] Is there a null statement that does nothing? To: "michael rice" Cc: haskell-cafe@haskell.org Date: Wednesday, October 21, 2009, 8:49 PM Yes, an if statement must have both 'then' and 'else' branches. As an example, what if you had
let a = if b == 2 then True else False
and you were missing an else branch? What would 'a' get assigned to?
The if statement "returns" a value so must have both branches.
However, in a monadic constraint, there are the functions 'when' and 'unless.' They allow conditional evaluation of expressions in a monadic context. For example,
main = do line <- getLine when (line == "hello") putStrLn "Hello back!"
Cheers, - Tim
On Wed, Oct 21, 2009 at 7:43 PM, michael rice
> wrote: It looks like both the THEN and the ELSE in an IF expression must each have an expression. What's a graceful way to do nothing in either or both slots, kind of like the Fortran CONTINUE statement.
--mr
================
[michael@localhost ~]$ ghci GHCi, version 6.10.3: http://www.haskell.org/ghc/ :? for help Loading package ghc-prim ... linking ... done. Loading package integer ... linking ... done. Loading package base ... linking ... done. Prelude> if (1==1) then else
<interactive>:1:15: parse error on input `else' Prelude> if (1==1) then True else
<interactive>:1:24: parse error (possibly incorrect indentation) Prelude> if (1==1) then True else False True Prelude>
_______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe

On 2009-10-21 18:27 -0700 (Wed), michael rice wrote:
Those nested IF/THEN/ELSEs are real killers. I kind of use them to sort out my thoughts, then end up with a nested mess. The restructuring to WHENs went smoothly and looks a lot cleaner besides.
Indeed. Monadic control flow is one of the basic keys to being able
to write nice code in Haskell; it's the moral equivalant of using
polymorphism rather than than "case" or "switch" in OO languages. (Well,
some would disagree, but that gets into the whole OO vs. functional
debate.)
You'll probably want to spend some time with one of the zillion monad
tutorials at some point (I like "All About Monads") to learn more about
these things.
BTW, look up the source code for "when". :-)
http://haskell.org/ghc/docs/latest/html/libraries/base/src/Control-Monad.htm...
cjs
--
Curt Sampson

Hi Curt,
Thanks for the tips. Looks like return () would be a good candidate for that null statement I was seeking earlier.
Michael
--- On Sun, 10/25/09, Curt Sampson
Those nested IF/THEN/ELSEs are real killers. I kind of use them to sort out my thoughts, then end up with a nested mess. The restructuring to WHENs went smoothly and looks a lot cleaner besides.
Indeed. Monadic control flow is one of the basic keys to being able
to write nice code in Haskell; it's the moral equivalant of using
polymorphism rather than than "case" or "switch" in OO languages. (Well,
some would disagree, but that gets into the whole OO vs. functional
debate.)
You'll probably want to spend some time with one of the zillion monad
tutorials at some point (I like "All About Monads") to learn more about
these things.
BTW, look up the source code for "when". :-)
http://haskell.org/ghc/docs/latest/html/libraries/base/src/Control-Monad.htm...
cjs
--
Curt Sampson

Dan Weston schrieb:
If you have a long if/else if/else chain, you might consider a trivial case statement with guards. Whether you think this is attractive is a matter of taste, but it has the fall-through semantics you want and ghc optimizes the _ pattern matching away:
f x = case () of _| x == 2 -> 22 _| x == 4 -> 44 _| x == 7 -> 77 _| otherwise -> 55
f 4 44 f 9 55

Hello michael, Thursday, October 22, 2009, 4:59:43 AM, you wrote: "return ()" does the trick if another branch also returns ()
Thanks guys,
I understand what you're telling me, but have some nested IFs and just want to fall through on one of the ELSES but then I end up with two ELSES in a row and nothing between them. Oh, well, on to restructuring.
Michael
--- On Wed, 10/21/09, Tim Wawrzynczak
wrote:
From: Tim Wawrzynczak
Subject: Re: [Haskell-cafe] Is there a null statement that does nothing? To: "michael rice" Cc: haskell-cafe@haskell.org Date: Wednesday, October 21, 2009, 8:49 PM
Yes, an if statement must have both 'then' and 'else' branches. As an example, what if you had
let a = if b == 2 then True else False
and you were missing an else branch? What would 'a' get assigned to?
The if statement "returns" a value so must have both branches.
However, in a monadic constraint, there are the functions 'when' and 'unless.' They allow conditional evaluation of expressions in a monadic context. For example,
main = do line <- getLine when (line == "hello") putStrLn "Hello back!"
Cheers, - Tim
On Wed, Oct 21, 2009 at 7:43 PM, michael rice
wrote: It looks like both the THEN and the ELSE in an IF expression must each have an expression. What's a graceful way to do nothing in either or both slots, kind of like the Fortran CONTINUE statement.
--mr
================
[michael@localhost ~]$ ghci GHCi, version 6.10.3: http://www.haskell.org/ghc/ :? for help Loading package ghc-prim ... linking ... done. Loading package integer ... linking ... done. Loading package base ... linking ... done. Prelude>> if (1==1) then else
<interactive>:1:15: parse error on input `else' Prelude>> if (1==1) then True else
<interactive>:1:24: parse error (possibly incorrect indentation) Prelude>> if (1==1) then True else False True Prelude>>
_______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
-- Best regards, Bulat mailto:Bulat.Ziganshin@gmail.com

On Wed, Oct 21, 2009 at 07:49:14PM -0500, Tim Wawrzynczak wrote:
Yes, an if statement must have both 'then' and 'else' branches. As an example, what if you had
let a = if b == 2 then True else False
and you were missing an else branch? What would 'a' get assigned to?
The if statement "returns" a value so must have both branches.
By the way, it helps to be precise with language here: "statement" usually indicates an instruction which causes some effect to happen. "Expression" indicates something which evaluates to a value. Haskell doesn't have "if statements" but it does have "if expressions". It makes sense for an if *statement* (in imperative languages like C) to have an optional else clause, since "do nothing" is a perfectly valid *statement*. But it doesn't make sense for an if *expression* to have a missing else, since it must evaluate to something and (in general) there is no "null value" that could be used. Of course, as others have noted, in a monadic context there IS a special "null value", namely return (), which can be used to indicate "do nothing". -Brent

Hi Brent, Re: '"if" expressions, not statements' is an elegant clarification, one definitely for the haskellwiki, if not there already. Just for completeness' sake, bottom is a value for any expression. Wouldn't making the else clause optional by defaulting to "undefined" worthy of consideration for Evil Haskell? -- Kim-Ee Brent Yorgey-2 wrote:
On Wed, Oct 21, 2009 at 07:49:14PM -0500, Tim Wawrzynczak wrote:
Yes, an if statement must have both 'then' and 'else' branches. As an example, what if you had
let a = if b == 2 then True else False
and you were missing an else branch? What would 'a' get assigned to?
The if statement "returns" a value so must have both branches.
By the way, it helps to be precise with language here: "statement" usually indicates an instruction which causes some effect to happen. "Expression" indicates something which evaluates to a value. Haskell doesn't have "if statements" but it does have "if expressions". It makes sense for an if *statement* (in imperative languages like C) to have an optional else clause, since "do nothing" is a perfectly valid *statement*. But it doesn't make sense for an if *expression* to have a missing else, since it must evaluate to something and (in general) there is no "null value" that could be used. Of course, as others have noted, in a monadic context there IS a special "null value", namely return (), which can be used to indicate "do nothing".
-Brent _______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
-- View this message in context: http://www.nabble.com/Is-there-a-null-statement-that-does-nothing--tp2600244... Sent from the Haskell - Haskell-Cafe mailing list archive at Nabble.com.

On Tue, Oct 27, 2009 at 10:08 AM, Kim-Ee Yeoh
Hi Brent,
Re: '"if" expressions, not statements' is an elegant clarification, one definitely for the haskellwiki, if not there already.
Just for completeness' sake, bottom is a value for any expression. Wouldn't making the else clause optional by defaulting to "undefined" worthy of consideration for Evil Haskell?
Doesn't that already exist in 'case x of True -> ...'?

Hello Kim-Ee, Tuesday, October 27, 2009, 8:08:27 PM, you wrote:
Just for completeness' sake, bottom is a value for any expression. Wouldn't making the else clause optional by defaulting to "undefined" worthy of consideration for Evil Haskell?
in this case you will get an exception when condition is false (when 'if' used in expression) -- Best regards, Bulat mailto:Bulat.Ziganshin@gmail.com

On Tue, Oct 27, 2009 at 7:07 PM, Bulat Ziganshin
Hello Kim-Ee,
Tuesday, October 27, 2009, 8:08:27 PM, you wrote:
Just for completeness' sake, bottom is a value for any expression. Wouldn't making the else clause optional by defaulting to "undefined" worthy of consideration for Evil Haskell?
in this case you will get an exception when condition is false (when 'if' used in expression)
Yes, that's why it's evil. Or.. I know! ifWithoutElse :: a -> Bool -> Maybe a (Wait...) -- Svein Ove Aas
participants (11)
-
Brent Yorgey
-
Bulat Ziganshin
-
Curt Sampson
-
Dan Weston
-
Evan Laforge
-
Henning Thielemann
-
Kim-Ee Yeoh
-
michael rice
-
Svein Ove Aas
-
Thomas DuBuisson
-
Tim Wawrzynczak