3
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

上面抛出以下错误:

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

我相信它是因为它期望第二个参数是 type Eff,但是由于第二个参数Maybe引入的使用head最终是 type Maybe

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

问题是,我不知道如何解决这个问题。我不能有一个Maybe有效的代码块吗?

4

2 回答 2

5

Maybe可以在do块中使用,但块中的所有操作都必须是Maybe asome的类型a

对于Eff eff- 你可以使用Eff effwith也是如此do,但所有动作都必须是Eff eff a某些类型的a

您不能在一个do块中混合和匹配两种类型的效果。

看起来您想在Maybe amonaddoEff eff. 你有几个选择:

  • 使用Data.Array.Unsafe.headwhich 会给你一个 unwrapped Tuple,你可以fst直接调用它。
  • 值的模式匹配Maybe以决定Effmonad 中的操作过程:

    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 ..
    
于 2014-07-28T03:12:39.440 回答
2

在这个例子中,也可以使用traverse_from Data.Foldable

由于您正在使用Maybe (Tuple String String)Maybe有一个Foldable实例,并且Eff e有一个应用实例,您可以使用traverse_而不是(<$>).

您只需要Tuple String String -> Eff e a为一些a. 如果您编写fstand fprint,您将得到准确的结果。

你的例子变成

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" $ 
    traverse_ (fst >>> fprint) $ head sampleRoutes
于 2014-09-10T06:10:09.867 回答