如何在列表与单个元素上进行模式匹配
How to pattern match on list vs single element
我想了解如何在 Erlang 中针对单个元素与列表进行模式匹配:
guarded(T) when T>5 ; T<3 -> 3+T;
guarded([X,Y]) when X>3,Y>3 ->{X+1,Y+1};
guarded([X,_|[T,_]]) when X rem 2==0, T rem 2 =/= 1-> [T,X];
guarded(_)->"something else".
guarded([1,2,3]). -> goes into case 1 , how can i make sure it doesn't (and goes to last case)
** exception error: an error occurred when evaluating an arithmetic expression
in function main:guarded/1
当我想在单个上进行模式匹配时,我需要将第一个案例放在哪里 elements.I 意味着我想要一个适用于单个元素的案例和一个通配符模式(最后表达式).
你可以给你的守卫添加一个is_list/1
检查来检查T
不是一个列表:
guarded(T) when not is_list(T) andalso (T>5 orelse T<3) -> 3+T;
guarded([X,Y]) when X>3, Y>3 ->{X+1,Y+1};
guarded([X,_|[T,_]]) when X rem 2==0, T rem 2 =/= 1-> [T,X];
guarded(_)->"something else".
或者您可以使用 is_number/1
or is_integer/1
分别检查 T
是数字还是整数:
guarded(T) when is_number(T) andalso (T>5 orelse T<3) -> 3+T;
guarded([X,Y]) when X>3, Y>3 ->{X+1,Y+1};
guarded([X,_|[T,_]]) when X rem 2==0, T rem 2 =/= 1-> [T,X];
guarded(_)->"something else".
作为 Vinoski 答案的替代方法,您还可以将不太具体的模式移到末尾,这样列表会首先匹配:
guarded([X,Y]) when X>3,Y>3 ->{X+1,Y+1};
guarded([X,_|[T,_]]) when X rem 2==0, T rem 2 =/= 1-> [T,X];
guarded(T) when T>5 ; T<3 -> 3+T;
guarded(_)->"something else".
但在这种特定情况下它不会很好地工作,因为像 guarded([1,1])
这样的东西仍然不会匹配前两个分支但会匹配 T
一个;这是因为 Erlang allows comparing any two values 只考虑列表大于数字。
I mean how does a method like is_list
(mentioned above) implemented?
使用 erlang,您可以像这样实现 is_list()
:
-module(my).
-compile([export_all]).
islist([]) -> % empty list
true;
islist([_|_]) -> % non-empty list
true;
islist(_) -> % anything else
false.
当你调用一个函数时,erlang 从定义中的第一个函数子句开始,并尝试将函数调用中指定的参数与函数定义中的参数相匹配。如果没有匹配,erlang 会尝试下一个函数子句。当找到匹配项时,相应的函数体就会执行。如果 none 个函数子句匹配,则会出现 function_clause
错误。
在shell:
~/erlang_programs$ erl
Erlang/OTP 17 [erts-6.4] [source] [64-bit] [smp:4:4] [async-threads:10] [hipe] [kernel-poll:false]
Eshell V6.4 (abort with ^G)
1> c(my).
{ok,my}
2> my:islist(3).
false
3> my:islist({1, 2}).
false
4> my:islist([1, 2]).
true
5> my:islist([]).
true
6> my:islist("abc").
true
在第 6 行中,您应该知道 "abc"
对于整数列表 [97, 98, 99]
是 shorthand。在 erlang 中,对于包含双引号字符串中字符的整数代码点的列表,双引号字符串是 shorthand。
我想了解如何在 Erlang 中针对单个元素与列表进行模式匹配:
guarded(T) when T>5 ; T<3 -> 3+T;
guarded([X,Y]) when X>3,Y>3 ->{X+1,Y+1};
guarded([X,_|[T,_]]) when X rem 2==0, T rem 2 =/= 1-> [T,X];
guarded(_)->"something else".
guarded([1,2,3]). -> goes into case 1 , how can i make sure it doesn't (and goes to last case)
** exception error: an error occurred when evaluating an arithmetic expression in function main:guarded/1
当我想在单个上进行模式匹配时,我需要将第一个案例放在哪里 elements.I 意味着我想要一个适用于单个元素的案例和一个通配符模式(最后表达式).
你可以给你的守卫添加一个is_list/1
检查来检查T
不是一个列表:
guarded(T) when not is_list(T) andalso (T>5 orelse T<3) -> 3+T;
guarded([X,Y]) when X>3, Y>3 ->{X+1,Y+1};
guarded([X,_|[T,_]]) when X rem 2==0, T rem 2 =/= 1-> [T,X];
guarded(_)->"something else".
或者您可以使用 is_number/1
or is_integer/1
分别检查 T
是数字还是整数:
guarded(T) when is_number(T) andalso (T>5 orelse T<3) -> 3+T;
guarded([X,Y]) when X>3, Y>3 ->{X+1,Y+1};
guarded([X,_|[T,_]]) when X rem 2==0, T rem 2 =/= 1-> [T,X];
guarded(_)->"something else".
作为 Vinoski 答案的替代方法,您还可以将不太具体的模式移到末尾,这样列表会首先匹配:
guarded([X,Y]) when X>3,Y>3 ->{X+1,Y+1};
guarded([X,_|[T,_]]) when X rem 2==0, T rem 2 =/= 1-> [T,X];
guarded(T) when T>5 ; T<3 -> 3+T;
guarded(_)->"something else".
但在这种特定情况下它不会很好地工作,因为像 guarded([1,1])
这样的东西仍然不会匹配前两个分支但会匹配 T
一个;这是因为 Erlang allows comparing any two values 只考虑列表大于数字。
I mean how does a method like
is_list
(mentioned above) implemented?
使用 erlang,您可以像这样实现 is_list()
:
-module(my).
-compile([export_all]).
islist([]) -> % empty list
true;
islist([_|_]) -> % non-empty list
true;
islist(_) -> % anything else
false.
当你调用一个函数时,erlang 从定义中的第一个函数子句开始,并尝试将函数调用中指定的参数与函数定义中的参数相匹配。如果没有匹配,erlang 会尝试下一个函数子句。当找到匹配项时,相应的函数体就会执行。如果 none 个函数子句匹配,则会出现 function_clause
错误。
在shell:
~/erlang_programs$ erl
Erlang/OTP 17 [erts-6.4] [source] [64-bit] [smp:4:4] [async-threads:10] [hipe] [kernel-poll:false]
Eshell V6.4 (abort with ^G)
1> c(my).
{ok,my}
2> my:islist(3).
false
3> my:islist({1, 2}).
false
4> my:islist([1, 2]).
true
5> my:islist([]).
true
6> my:islist("abc").
true
在第 6 行中,您应该知道 "abc"
对于整数列表 [97, 98, 99]
是 shorthand。在 erlang 中,对于包含双引号字符串中字符的整数代码点的列表,双引号字符串是 shorthand。