解决效果和Maybes

时间:2014-07-28 00:26:07

标签: purescript

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.

我相信它,因为它期望第二个参数类型Eff,但是因为 Maybe引入的head第二个参数的使用最终变为Maybe类型。

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

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

2 个答案:

答案 0 :(得分:4)

Maybe可以在do块中使用,但是对于某些Maybe a,块中的所有操作都必须是a类型。

对于Eff eff也是如此 - 您可以将Eff effdo一起使用,但对于某些Eff eff a,所有操作都必须属于a类型。

您无法在do块中混合和匹配两种类型的效果。

看起来您希望在monad为Maybe a的{​​{1}}块中使用do类型的值。你有几个选择:

  • 使用Eff eff将为您提供解包的Data.Array.Unsafe.head,您可以直接致电Tuple
  • fst值上的模式匹配,以决定Maybe monad中的操作过程:

    Eff

答案 1 :(得分:2)

在此示例中,还可以使用Data.Foldable中的traverse_

由于您使用的是Maybe (Tuple String String)Maybe有一个Foldable个实例,Eff e有一个应用实例,因此您可以使用traverse_(<$>)

您只需要为某些Tuple String String -> Eff e a提供功能a。如果你撰写fstfprint,那就完全可以了。

您的示例变为

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