繁体   English   中英

Erlang初学者:找到外围吗?

[英]Erlang Beginner: Find Perimeter?

我正在学习Erlang并尝试此处提到的问题,因为

3. Write a function mathStuff:perimeter(Form) which computes the perimeter of different forms. Form can be one of:

    {square,Side}
    {circle,Radius}
    {triangle,A,B,C}

所以,我的解决方案是

-module(mathStuff).
-export([perimeter/1]).

perimeter(Form) ->
        case element(1, Form) of
                square          -> io:format("perimeter for square is ~p~n", [4*element(2, Form)]);
                circle          -> io:format("perimeter for circle is ~p~n", [2*math:pi()*element(2, Form)]);
                triangle        -> io:format("perimeter for triangle ~p~n", [element(2, Form) + element(3, Form) + element(4, Form)])
        end.
~             

当我跑步时我得到

38> c("mathStuff.erl").              
{ok,mathStuff}
39> mathStuff:perimeter({circle, 2}).
perimeter for circle is 12.566370614359172
ok
40> mathStuff:perimeter({rectangle, 2}).
** exception error: no case clause matching rectangle
     in function  mathStuff:perimeter/1 (mathStuff.erl, line 5)
41> mathStuff:perimeter({square, 2}).   
perimeter for square is 8
ok
42> mathStuff:perimeter({traingle, 1, 2, 3}).
** exception error: no case clause matching traingle
     in function  mathStuff:perimeter/1 (mathStuff.erl, line 5)
43> mathStuff:perimeter({triangle, 1, 2, 3}).
perimeter for triangle 6
ok

但这是不正确的,因为我也可以

44> mathStuff:perimeter({triangle, 1, 2, 3, 4}).
perimeter for triangle 6
ok
45> 

解决此问题的更好方法是什么,如何才能更具体地说明类型和参数?

第一个错误的原因是您的case ... end表达式不匹配rectangle ,因此它无法匹配任何内容。 与大多数命令式语言不同,通常需要使用功能性语言中的case表达式来匹配至少一个子句-否则,该表达式应求值是什么?

解决此问题的一种更惯用的方法是在函数头处进行模式匹配 ,如下所示:

perimeter({square, Side}) ->
    io:format("perimeter for square is ~p~n", [4*Side]);
...
perimeter({triangle, A, B, C}) ->
    io:format("perimeter for triangle ~p~n", [A + B + C]).

注意,功能子句使用;分隔; ,最后一个子句以终止.

从本质上讲,Erlang无需您从带有element/2的元组中手动选择字段,而是可以使用模式匹配来“解压缩”该元组。 我认为,这是使用具有代数数据类型的功能语言的最大好处之一。

顺便说一句,即使对于诸如perimeter({triangle, 1, 2, 3, 4})类的错误调用也能获得正确的结果,原因是您没有使用模式匹配,而是手动选择了元组的相关字段。 您从未检查过元组不长! 模式匹配执行一种输入验证作为副作用,因为这样的表达式如下:

{A, B, C} = {1, 2, 3, 4}

确保因匹配错误而失败。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM