为什么我不能在`foldr`的lambda函数中使用“isJust”?
我目前正在用 Haskell 为原始编程语言编写解释器。我试图在解释之前查看正在分析的当前程序是否正确键入。基本上我最终得到的是一个名为的列表maybeList,如果它们正确,则保存初始化变量的映射,如果它们不正确,Nothing则为 s,如下所示:
[Maybe [(k,v)]]
我正在尝试使用此功能折叠此列表
foldr (x y -> (isJust x) && (isJust y)) True maybeList
根据我对 Haskell 和foldr函数的了解,这应该有效。但是,它给了我错误:
Couldn't match expected type ‘Bool’ with actual type ‘Maybe a0’ In the expression: foldr ( x y -> (isJust x) && (isJust y)) True maybeList
我要问的是为什么编译器不知道该 isJust 函数返回一个布尔值,它一直将它视为一种 Maybe a0 类型?
PS我知道一个简单的方法 elem Nothing maybeList 可以代替这个。但我想了解为什么这不起作用
回答
的reduce函数foldr将与初始元素类型相同的第二个参数作为第二个参数:
foldr (x y -> (isJust x) && (isJust y)) True maybeList
-- _______________________________/
-- |
-- these two must be the same type
所以y是 typeBool但你正在考虑它的 type Maybe a。
因此,foldr (x y -> (isJust x) && y) True maybeList是正确的解决方案。
回答
Afoldr将accumulator作为第二个参数。确实,类型foldr是:
foldr :: Foldable f => (a -> b -> b) -> b -> f a -> b
这b是从概念上从右到左的累加器的类型,而a是列表的项目。
由于您使用Truein ,因此这意味着累加器,因此也是。foldr (x y -> isJust x && isJust y) TrueyBool
我们可以通过以下方式实现:
foldr (x y -> isJust x && y) True maybeList
然而,我们不需要foldr这里。您在这里确定的是所有项目是否都是Just …. 因此,我们可以使用all :: Foldable f => (a -> Bool) -> f a -> Bool:
all isJust maybeList