2

I'm writing hspec test suite which uses binding as follows:

it "should take the x component" $ do
    (getX $ coord $ [1,0,2]) `shouldBe` 1

However, for more complicated statement, one-liner is not conveniently readable so I try to strip the variable out in where expression:

it "should take the x component" $ do
    (getX c) `shouldBe` 1
       where c = coord $ [1,0,2]

But this turns out illegal statement in Haskell. Using let does not succeed either.

it "should take the x component" $ do
    let c = coord $ [1,0,2]
    in (getX c) `shouldBe` 1

How can I assign a helper variable for the same purpose as let or where within do binding? Exploring the documentations but can't find a good example though.

TaoPR
  • 5,932
  • 3
  • 25
  • 35
  • By the way, the parentheses around `getX c` are redundant. So is the `$` between `coord` and `[1,0,2]`. And `getX $ coord $ [1,0,2]` should probably be written either `getX (coord [1,0,2])` or as `getX . coord $ [1,0,2]`. – dfeuer Jan 26 '16 at 03:55
  • Thanks for your suggestion. Actually the statement was just a simplified sample for the question. My actual test statement is much more complicated for grouping so I really need either `let` or `where`. – TaoPR Jan 26 '16 at 04:03
  • I wasn't talking about the `let` or `where`, but about how you wrote those two expressions. – dfeuer Jan 26 '16 at 04:16

2 Answers2

4

It's hard to say why the first one fails without seeing more context. The second fails because let works differently in do blocks. Either indent the in another couple spaces or delete the keyword in and make the rest of the line align with the keyword let.

dfeuer
  • 48,079
  • 5
  • 63
  • 167
  • I haven't realised this needs extra indentation of `in` or even omitting it. Sounds a bit syntactic inconsistency to me. – TaoPR Jan 26 '16 at 04:02
  • 2
    @TaoP.R. It follows from the [general indentation rules](http://stackoverflow.com/a/33010779/3234959) which apply to `do`. Basically, indented in that way it means `do { let c = ... ; in getX c ... }` making `in ...` the second entry in the `do` block, apart from the first entry, which is wrong. By the way, you can also simply remove `do` here, since there's only one entry in that block, so we can not start a block at all and forget indentation. – chi Jan 26 '16 at 08:50
4

let statements inside do do not need the in keyword. In other words, try this:

it "should take the x component" $ do
    let c = coord $ [1,0,2]
    (getX c) `shouldBe` 1
Samee
  • 796
  • 5
  • 13