More struggles with do notation

This is defeating me. Can anyone tell me where I’m going wrong here?

selectFromDocument :: (V (Array String) QuerySelector) -> HTMLDocument -> Effect (V Errors HTMLInputElement)
selectFromDocument (V (Right sel)) doc = do
  m <- querySelector sel (toParentNode doc)
  pure $ V $ note (Left ("Cannot find element using selector `" <> showQS sel <> "`.")) (m >>= fromElement)
selectFromDocument err _ = pure err

QuerySelector is just a String.

querySelector :: QuerySelector -> ParentNode -> Effect (Maybe Element)

So shouldn’t m be Maybe Element? Then:

fromElement :: Element -> Maybe HTMLInputElement

Then shouldn’t bind return Maybe HTMLInputElement? Then:

note :: forall a b. a -> Maybe b -> Either a b

And won’t that return an Either that gets wrapped in a V and then pure makes it back into an Effect?

But I get an error on this line: m <- querySelector sel (toParentNode doc) that says “Could not match type Effect with type Either t0 while trying to match type Effect (Maybe Element)”. This makes zero sense to me. Can anyone explain?

Error reporting for do-notation can be a little misleading at times, this has been a thing in the compiler for quite a while now because of how PureScript desugars do-notation into bind calls. In this case I think the line

m <- querySelector sel (toParentNode doc)

is perfectly fine, since:

m :: Maybe Element

I think the issue might be coming from the call to note, since you’re passing an Either to it as in:

  pure $ V $ note (Left ("Cannot find element using selector `" <> showQS sel <> "`.")) (m >>= fromElement)

Rather than:

  pure $ V $ note ("Cannot find element using selector `" <> showQS sel <> "`.") (m >>= fromElement)

That appears to have worked. Thanks! On to the next one …