我是Erlang的新手,正在尝试编写一个函数,当传递一个Point记录(x,y坐标)和一个Point记录列表(x,y坐标列表)时,如果具有指定x和y坐标的Point记录是列表中的元素(即已经存在),则返回true,否则返回false。
下面是点记录的定义:
-record(point, {x, y})
字符串
这是函数的签名:
contains_point(Point, List)
型
我试着在Erlang文档中查找类似的问题,但没有找到我要找的东西。
我也尝试了以下代码:
contains_point(Point, List)->
Found = fun(Point) -> lists:member(Point, List) end,
case lists:any(Found, List) of
true ->
yes;
false ->
no
end.
型
但是得到了警告消息,“变量'Point'在'fun'中隐藏”和“变量'Point'未使用”。
会很感激任何帮助,谢谢!
2条答案
按热度按时间kcugc4gi1#
你的函数有多个问题,未使用和隐藏的变量警告暗示了这一点。
字符串
lists:any/2
函数的第一个参数是一个 predicate 函数,该 predicate 函数将被第二个参数(列表)的每个元素调用,直到 predicate 返回true或列表耗尽。这里的 predicate 是匿名函数Found
,它将返回将其列表元素参数传递给lists:member/2
的结果。但是lists:member/2
函数也会遍历其列表参数,如果它的第一个参数匹配列表元素,则返回true,否则返回false,这意味着Found
predicate 每次lists:any/2
调用它时都会检查整个列表,这是非常低效的。你的函数也返回
yes
或no
,但根据你的描述,它应该返回一个布尔值。修复函数的最简单方法是返回
lists:member/2
的结果,因为它会遍历一个列表来寻找匹配:型
或者,如果你不想使用
lists
模块,你可以编写函数来遍历列表本身并检查匹配:型
1.第一个子句匹配空列表,因此返回false。
1.第二个子句提供了真实的情况,因为它的第一个参数和列表的头部都是相同的
Point
值,所以它们匹配。1.第三个子句在
Point
不匹配列表的头部时进行匹配;它使用Point
和列表的尾部递归调用contains_point/2
。这种方法本质上就是
lists:member/2
所做的。uplii1fm2#
字符串
这是一个匿名函数的定义,在erlang中称为
fun
。当你定义任何函数时,匿名或其他,你指定参数变量,例如Point,然后当你调用函数时,erlang会把你在函数调用中指定的参数赋给函数定义中的形参变量。然后你可以在函数定义中使用形参变量来完成你想要什么都行值得注意的是,匿名函数定义等价于:
型
换句话说,函数定义中的 parameter 变量与函数定义之外的任何其他变量都没有关系。Erlang给出了两个警告:
型
这意味着你在这个函数参数列表中使用了相同的变量名:
型
就像你在这个(匿名)函数参数列表中所做的那样:
型
但它们彼此之间并不相关。
型
你得到这个警告是因为这里的参数变量Point:
型
在
contains_point()
函数定义体中从不使用。你可以这样做:
型
在这种情况下,函数并没有定义一个“隐藏”另一个变量的参数变量,因此匿名函数定义中的
Point
变量与do_stuff()
参数列表中的Point
变量相同。