如何解决为什么我不能在 `foldr` 的 lambda 函数中使用“isJust”?
我目前正在用 Haskell 为原始编程语言编写解释器。
我试图在解释之前查看正在分析的当前程序是否正确键入。基本上我最终得到的是一个名为 maybeList
的列表,如果它们是正确的,它包含初始化变量的映射,如果它们不正确,则包含 Nothing
,如下所示:
[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
类型?
附言我知道一个简单的 elem Nothing maybeList
可以代替它。但我想了解为什么这不起作用
解决方法
foldr
的 reducing 函数将与初始元素类型相同的第二个参数作为第二个参数:
foldr (\x y -> (isJust x) && (isJust y)) True maybeList
-- \_______________________________/
-- |
-- these two must be the same type
所以 y
是 Bool
类型,但您正在考虑它是 Maybe a
类型。
因此,foldr (\x y -> (isJust x) && y) True maybeList
是正确的解决方案。
A /usr/bin/omxplayer.bin: relocation error: /lib/arm-linux-gnueabihf/libpthread.so.0: symbol _libc_dlopen_mode version GLIBC_PRIVATE not defined in file libc.so.6 with link time reference
将 accumulator 作为第二个参数。实际上,foldr
的类型是:
foldr
这里的 foldr :: Foldable f => (a -> b -> b) -> b -> f a -> b
是概念上从右到左的累加器的类型,而 b
是列表的项目。
由于您在 a
中使用 True
,因此这意味着累加器,因此 foldr (\x y -> isJust x && isJust y) True
也是 y
类型。
我们可以通过以下方式实现:
Bool
然而,我们在这里不需要 foldr (\x y -> isJust x && y) True maybeList
。您在这里确定的是所有项目是否都是 foldr
。因此,我们可以使用 all :: Foldable f => (a -> Bool) -> f a -> Bool
:
Just …
,
问题出在 isJust y
部分,y
是列表尾部折叠的结果,因此类型为 Bool
。就像您提供给 True
函数的第二个参数 foldr
一样。
您不能对 isJust
类型的值调用 Bool
。一个简单的解决方法是省略 isJust
。
我得到的完整错误信息是:
<interactive>:3:16: error:
• Couldn't match expected type ‘Maybe a’ with actual type ‘Bool’
• In the expression: (isJust x) && (isJust y)
In the first argument of ‘foldr’,namely
‘(\ x y -> (isJust x) && (isJust y))’
In the expression:
foldr (\ x y -> (isJust x) && (isJust y)) True maybeList
• Relevant bindings include
y :: Maybe a (bound at <interactive>:3:11)
it :: Maybe a (bound at <interactive>:3:1)
<interactive>:3:42: error:
• Couldn't match expected type ‘Maybe a’ with actual type ‘Bool’
• In the second argument of ‘foldr’,namely ‘True’
In the expression:
foldr (\ x y -> (isJust x) && (isJust y)) True maybeList
In an equation for ‘it’:
it = foldr (\ x y -> (isJust x) && (isJust y)) True maybeList
• Relevant bindings include
it :: Maybe a (bound at <interactive>:3:1)
这表明 GHC 对它的解释是错误的。它认为您打算让某些 Maybe a0
的结果为 a0
类型。那么 foldr
的第二个参数,即 True
类型错误,lambda 的结果类型错误。
foldr
的类型是
foldr :: (a -> b -> b) -> b -> t a -> b
这意味着您的 lamda 表达式应该采用 Bool
作为它的第二个参数,而在您的情况下,它需要一个 Maybe
。
@Ismor 有正确的解释。
注意 Haskell 有一个库函数*
all :: (a -> Bool) -> [a] -> Bool
all f = foldr (\x y -> f x && y) True
所以foldr (\x y -> isJust x && y) True maybeList
的解等价于all isJust maybeList
。
因此,解决方案与规范完全一样:检查 maybeList
的所有元素是否都是 Just
=> all isJust maybeList
。
*
从技术上讲,all
的类型是
all :: (Foldable f) => (a -> Bool) -> f a -> Bool
因此,可以检查实现 Foldable
类型类的任何类型构造函数,以查看其所有元素是否满足特定谓词。因此,您可以将其用于树、列表、Maybes 等。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。