Home > Back-end >  Sequentially composing two `Spec` types
Sequentially composing two `Spec` types

Time:12-15

Assuming

testValidateFEN :: Spec
testBuildBoard :: Spec

and the module Test.hspec is imported.

I am reading the following line of code:

hspec (testValidateFEN >> testBuildBoard)

My questions are:

  • Does Spec have an instance of the Monad typeclass ?
  • Isn't that line of code equivalent to hspec testBuildBoard since the first action result is discarded ?

CodePudding user response:

  1. Yes, Spec does have a Monad instance.
  2. The result of the first action is discarded, but its effect is still carried out.

Could you explain how would you de-sugar the expression hspec (testValidateFEN >> testBuildBoard)

If you look at the definition of Spec, you'll see that it's a synonym for SpecWith, which in turn is a synonym for SpecM, which in turn is a monad stack of Writer IO wrapped in a newtype, with the Monad instance derived from the underlying stack.

So when you combine two of those with a >> b, that desugars into a >>= \_ -> b according to the definition of >>, which means "first run a, then take its output, throw it away, and then run b" - according to the description in the Monad class.

As you combine testValidateFEN :: Spec and testBuildBoard :: Spec via >>, you get a new value, also of type Spec, which, when executed, would first execute testValidateFEN, take its return value, throw it away, and then execute testBuildBoard.

Now, the crucial thing to realize here is that the important "output" of these Spec actions is not in their return values, but in the list of SpecTree a values (see definition of SpecM) that they accumulate via the Writer monad as a side-effect of their execution. Therefore, if you execute testValidateFEN, it will accumulate some SpecTree a values via the Writer monad, and then if you execute testBuildBoard, it will accumulate some more SpecTree a values, and the total resulting list of [SpecTree a] would be the combined lists that testValidateFEN and testBuildBoard would have produced on their own.

  • Related