Nelson Tatius
Nelson Tatius

Reputation: 8053

'where' inside other expression

I can use let inside other expression.

foo n = (let a = True in (\x -> a)) 3

foo' n | n == 1 = let a = True in a
       | n /= 1 = False

But I can't do the same with where

foo n = ((\x -> a) where a = True) 3

foo' n | n == 1 = a where a = True
       | n /= 1 = False

1:20: parse error on input `where'

Is it really impossible in haskell or just my mistake?

Upvotes: 4

Views: 422

Answers (4)

applicative
applicative

Reputation: 8199

The claim that let is an expression is a bit off, it seems to me; in a do block it is a statement, though we say that there it abbreviates let ... in. The thing to say, I think, is

 let_in_ :: Statement -> Expression -> Expression
 _where_ :: Statement -> Statement  -> Statement

Thus the first part of a let is a statement and can be modified by a where. So for example

 foo n = (let a = b where b = True in (\x -> a)) 3

 bip = do 
     let a = b where b = let c = d where d = True in c
     return a

Similarly we can maybe say something like this:

 case_of_ :: Expression -> [Statement] -> Expression

so that e.g.

z x = case even x of 
   True -> d where d = x + 1
   False -> w - 1 where w = let a = x in a + 1 

Upvotes: 0

Ben
Ben

Reputation: 71590

let ... in ... is for introducing name bindings in an expression.

where is convenience syntax for giving local auxiliary definitions along with an equation. You can only use it as part of an equation (at the end), not in the middle of an arbitrary expression.

Their usage is not the same.

Upvotes: 1

Pubby
Pubby

Reputation: 53097

let is an expression while where is a clause. where is bound to syntactic constructs, let can be used anywhere expressions can.

You could of course write it like this:

foo n = ((\x -> a)) 3 where a = True

foo' n | n == 1 = a
       | n /= 1 = False
       where a = True

or like this:

foo n = (\a -> (\x -> a) 3) True

Upvotes: 10

Lee
Lee

Reputation: 144206

You need to put the where clause at the end:

foo n = ((\x -> a)) 3
  where a = True

foo' n | n == 1 = a
       | n /= 1 = False
  where a = True

The difference is that let is an expression, whereas where requires some other construct to be bound to. See let vs where

Upvotes: 4

Related Questions