Is it possible to use `case` inside of a `where` block?

I tried:

bar :: Int -> Int
bar x = y 
  where y = case x of
    1 -> 1
    _ -> 2

but I get a parse error on the first 1 in 1 -> 1.

Yes, you just need to indent the body of the definition of y = past the equals sign:

bar :: Int -> Int
bar x = y 
  where y = case x of
              1 -> 1
              _ -> 2
1 Like

PureScript and Haskell have what’s called the “offside” rule. When determining how to parse a whitespace sensitive block, it looks at the column of the token immediately following the keyword. Anything indented to at least that column is part of that block, but if something is indented less, it is not considered part of that block. Tokens that introduce whitespace sensitivity are where, of, let, and do.

-- These are part of the same do-block
example = do foo
             bar

-- These are not
example = do foo
          bar

In your example the where block starts at the column for y, so the branches of your case need to be indented past that.

3 Likes