- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我这样试过:
member e [] = False
member e xs = foldr (==) e xs
然后:
member 3 [1,2,3,4,5]
我收到此错误消息:
No instance for (Num Bool) arising from the literal `3'
In the first argument of `memb', namely `3'
我不知道这是什么意思...有人可以帮助我吗?
PS:member 是一个函数,给定一个元素和一个元素列表,返回该元素是否属于该列表。通常的实现是:
member a [] = False
member a (x:xs) | (a == x) = True
| otherwise = member a xs
PS2:完整代码
-- member:: Int -> [Int] -> Bool (Not necessary)
member e [] = False
member e xs = foldr (==) e xs
main = do
putStrLn (show( member 3 [1,2,3] ) )
最佳答案
您快完成了,但是您可以看到您的类型没有对齐。如果你给member
会更好一个明确的类型签名,我猜你想要类似的东西
member :: (Eq a) => a -> [a] -> Bool
这会让编译器提示说这不会在您尝试使用它时进行类型检查而不是失败。问题是 foldr (==)
类型为 Bool -> [Bool] -> Bool
,与您的预期不尽相同。
相反,你想要的是更像
member e xs
= foldr (||)
False
(map (e ==) xs)
我在这里将参数拆分到单独的行中,以便更容易看到 foldr
的参数是什么实际上是。这里的主要想法是将值列表转换为 Bool
的列表。 s,然后使用 or 运算符 ( ||
) 将列表缩减为单个 Bool
.由于 Haskell 默认是惰性的,map (e ==) xs
在 foldr
需要元素之前不会实际计算任何东西,因此您不必将列表中的每个元素与 e
进行比较.
你可以直接用 foldr
实现它使用更复杂的累加器(foldr
的第一个参数):
member e xs = foldr (\x acc -> if acc then x else e == x) False xs
可以等价地写成
member e xs = foldr (\x acc -> acc || e == x) False xs
注意在这种情况下我们必须如何执行 e == x
对于每个 x
在 xs
直到我们找到 acc
的情况是True
.这就是我选择map (e ==)
的原因之前,我只是将执行比较的步骤与累加值的步骤分开。
关于 foldr
要记住的一件事(和大多数其他折叠)是第二个参数,也称为初始值,必须与 foldr
的最终结果具有相同的类型。 .在这种情况下,您需要 foldr
返回 Bool
, 所以第二个参数必须是 Bool
如果您有足够新的 GHC 版本,解决这些问题的一个技巧是打洞。这些允许你在表达式中放入“洞”,编译器会告诉你那个洞应该是什么类型,所以如果你这样做
member :: Eq a => a -> [a] -> Bool
member e xs = foldr _1 _2 xs
GHC 会打印出来
Found hole `_1` with type: a -> Bool -> Bool
...
Relevant bindings include
xs :: [a]
e :: a
Found hole `_2` with type: Bool
...
Relevant bindings include
xs :: [a]
e :: a
这告诉你给foldr
的函数必须具有类型 a -> Bool -> Bool
并且初始值的类型必须为 Bool
.自 e
类型为 a
你不能把它放在那个洞里。这种技术可以帮助指导您定义函数,特别是当您不确定所有类型时,编译器会告诉您每个参数使用什么。
关于haskell - 在 Haskell 中使用 "member"实现函数 "foldr",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33089505/
C语言sscanf()函数:从字符串中读取指定格式的数据 头文件: ?
最近,我有一个关于工作预评估的问题,即使查询了每个功能的工作原理,我也不知道如何解决。这是一个伪代码。 下面是一个名为foo()的函数,该函数将被传递一个值并返回一个值。如果将以下值传递给foo函数,
CStr 函数 返回表达式,该表达式已被转换为 String 子类型的 Variant。 CStr(expression) expression 参数是任意有效的表达式。 说明 通常,可以
CSng 函数 返回表达式,该表达式已被转换为 Single 子类型的 Variant。 CSng(expression) expression 参数是任意有效的表达式。 说明 通常,可
CreateObject 函数 创建并返回对 Automation 对象的引用。 CreateObject(servername.typename [, location]) 参数 serv
Cos 函数 返回某个角的余弦值。 Cos(number) number 参数可以是任何将某个角表示为弧度的有效数值表达式。 说明 Cos 函数取某个角并返回直角三角形两边的比值。此比值是
CLng 函数 返回表达式,此表达式已被转换为 Long 子类型的 Variant。 CLng(expression) expression 参数是任意有效的表达式。 说明 通常,您可以使
CInt 函数 返回表达式,此表达式已被转换为 Integer 子类型的 Variant。 CInt(expression) expression 参数是任意有效的表达式。 说明 通常,可
Chr 函数 返回与指定的 ANSI 字符代码相对应的字符。 Chr(charcode) charcode 参数是可以标识字符的数字。 说明 从 0 到 31 的数字表示标准的不可打印的
CDbl 函数 返回表达式,此表达式已被转换为 Double 子类型的 Variant。 CDbl(expression) expression 参数是任意有效的表达式。 说明 通常,您可
CDate 函数 返回表达式,此表达式已被转换为 Date 子类型的 Variant。 CDate(date) date 参数是任意有效的日期表达式。 说明 IsDate 函数用于判断 d
CCur 函数 返回表达式,此表达式已被转换为 Currency 子类型的 Variant。 CCur(expression) expression 参数是任意有效的表达式。 说明 通常,
CByte 函数 返回表达式,此表达式已被转换为 Byte 子类型的 Variant。 CByte(expression) expression 参数是任意有效的表达式。 说明 通常,可以
CBool 函数 返回表达式,此表达式已转换为 Boolean 子类型的 Variant。 CBool(expression) expression 是任意有效的表达式。 说明 如果 ex
Atn 函数 返回数值的反正切值。 Atn(number) number 参数可以是任意有效的数值表达式。 说明 Atn 函数计算直角三角形两个边的比值 (number) 并返回对应角的弧
Asc 函数 返回与字符串的第一个字母对应的 ANSI 字符代码。 Asc(string) string 参数是任意有效的字符串表达式。如果 string 参数未包含字符,则将发生运行时错误。
Array 函数 返回包含数组的 Variant。 Array(arglist) arglist 参数是赋给包含在 Variant 中的数组元素的值的列表(用逗号分隔)。如果没有指定此参数,则
Abs 函数 返回数字的绝对值。 Abs(number) number 参数可以是任意有效的数值表达式。如果 number 包含 Null,则返回 Null;如果是未初始化变量,则返回 0。
FormatPercent 函数 返回表达式,此表达式已被格式化为尾随有 % 符号的百分比(乘以 100 )。 FormatPercent(expression[,NumDigitsAfterD
FormatNumber 函数 返回表达式,此表达式已被格式化为数值。 FormatNumber( expression [,NumDigitsAfterDecimal [,Inc
我是一名优秀的程序员,十分优秀!