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
代替有效的代码块吗?
答案 0 :(得分:4)
Maybe
可以在do
块中使用,但是对于某些Maybe a
,块中的所有操作都必须是a
类型。
对于Eff eff
也是如此 - 您可以将Eff eff
与do
一起使用,但对于某些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
。如果你撰写fst
和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