Search code examples
purescript

Resolving Effects and Maybes


spec = describe "Router" $ do

  let sampleRoutes = [( Tuple "/"  "views/index.yaml" ), 
                      ( Tuple "/foo" "views/foo.yaml" ), 
                      ( Tuple "/bar" "views/bar.yaml" )]

  it "should default to the first of the list" $ do
    r <- fst <$> head sampleRoutes
    fprint r

The above throws the following error:

Error in declaration spec
Cannot unify Data.Maybe.Maybe with Control.Monad.Eff.Eff u4505.

I believe its because it is expect a second argument that is of type Eff, but because of the use of Maybe introduced by head the second arguments ends up being of type Maybe instead.

it :: forall e a. String -> Eff e a -> Eff (it :: It | e) Unit

The problem is, I have no idea how to resolve this. Can I not have a Maybe instead an effectful block of code?


Solution

  • Maybe can be used in a do block, but all of the actions in the block have to be of type Maybe a for some a.

    The same is true for Eff eff - you can use Eff eff with do, but all actions have to be of type Eff eff a for some a.

    You can't mix and match the two types of effects within a do block.

    It looks like you want to use a value of type Maybe a inside a do block whose monad is Eff eff. You have a couple of options:

    • Use Data.Array.Unsafe.head which will give you an unwrapped Tuple, which you can call fst on directly.
    • Pattern match on the Maybe value to decide the course of action in the Eff monad:

      it "should default to the first of the list" $ do
        case head sampleRoutes of
          Nothing -> ... -- Handle empty array
          Just tuple -> fprint (fst tuple) -- Print the first component
        .. rest of do block ..