2016-12-08 2 views
0
increment([]) -> []; 
increment([H|T]) -> [H+1|increment(T)]. 

decrement([]) -> []; 
decrement([H|T]) -> [H-1|decrement(T)]. 

그래서이 코드가 있지만 자바에서 제대로 작동하는지 잘 모르겠습니다.erlang에서 증분을 수행하는 단계는 무엇입니까?

+0

예전에 비슷한 질문에 묘사 된 것과 거의 같습니다 : http://stackoverflow.com/questions/41008186/how-does-a-loop-simulation-works 그들은 어떻게 다른지 궁금하십니까? –

+0

예, 정말 혼란 스럽습니다^^ T –

답변

2

자바와 얼랭은 다른 짐승입니다. Erlang을 배울 때 Java에 대한 비교를 시도하는 것을 권장하지 않습니다. 특히 Java가 지금까지 알고있는 유일한 언어 인 경우 특히 그렇습니다. 게시 한 코드는 "기능 프로그래밍"이라는 패러다임의 좋은 예입니다. 나는 그 주제에 대해 당신이 무슨 일이 일어나는지 이해할 수 있도록 약간의 독서를하는 것이 좋습니다. Erlang이가는 한 이것을 깨기 위해 Erlang 함수가 Java 메소드와 완전히 다르다는 것을 이해해야합니다.

Java에서 메소드 서명은 메소드 이름과 인수 유형으로 구성됩니다. 반환 유형도 중요 할 수 있습니다. Java increment 메소드와 같은 함수는 List<Integer> increment(List<Integer> input)과 같이 작성 될 수 있습니다. Java 메소드의 본문은 아마도 한 번에 목록을 요소를 반복하고 하나 더하기 자체에 각 요소를 설정합니다 :

List<Integer> increment(List<Integer> input) { 
    for (int i = 0; i < input.size; i++) { 
     input.set(i, input.get(i) + 1); 
    } 
} 

얼랑이 공통점이 거의 아무것도 없습니다. 우선, erlang 함수의 "signature"는 함수의 이름과 속성입니다. Arity는 함수가 받아들이는 인수를 의미합니다. 따라서 증분 함수는 increment/1으로 알려져 있으며 그 고유 한 서명입니다. 함수 이름 뒤에 괄호 안에 인수 목록을 쓰는 방법은 전달 된 데이터의 패턴보다는 인수 유형과 관련이 없습니다. increment([]) -> ...과 같은 함수는 빈 목록 인 []을 전달하여 성공적으로 호출 할 수 있습니다. 마찬가지로 increment([Item]) -> ... 함수는 하나의 항목이 포함 된 목록을 전달하여 성공적으로 호출 할 수 있으며 increment([Item1, Item2]) -> ...에는 두 항목이 포함 된 목록이 전달되어야합니다. 데이터를 패턴과 일치시키는이 개념은 "패턴 일치"로 잘 알려져 있습니다. 많은 기능적 언어로 찾을 수 있습니다. Erlang 함수에서는 실행할 함수의 헤드를 선택하는 데 사용됩니다. 이것은 Java의 메소드 오버로딩과 근본적으로 유사합니다. 동일한 메소드로 많은 메소드를 사용할 수 있지만 인수 유형은 다릅니다. 그러나 Erlang 함수 헤드의 패턴은 패턴과 일치하는 인수의 다른 부분에 변수를 바인딩 할 수 있습니다.

코드 예에서 함수 increment/1에는 두 개의 머리가 있습니다. 첫 번째 헤드는 함수에 빈 목록을 전달한 경우에만 실행됩니다. 두 번째 헤드는 비어 있지 않은 목록을 함수에 전달한 경우에만 실행됩니다. 이 경우 두 변수, HT이 바인딩됩니다. H은 목록의 첫 번째 항목에 바인딩되고 T은 첫 번째 항목을 제외한 나머지 모든 항목을 의미하는 나머지 목록에 바인딩됩니다. [H|T] 패턴이 하나의 요소가 포함 된 목록을 포함하여 비어 있지 않은 목록과 일치하기 때문입니다.이 경우 T은 빈 목록에 바인딩됩니다. 따라서 바인딩 된 변수는 함수 본문에 사용될 수 있습니다.

함수 본문은 Erlang에서 새로운 목록을 생성하는 목록을 반복하는 매우 일반적인 형식입니다. 얼랭 (Erlang) 데이터는 불변이므로 자바와 다른 중요한 차이점이 있기 때문에 일반적입니다. 즉 위의 Java 코드 에서처럼 "목록의 요소 설정"과 같은 개념이 없습니다. 목록을 변경하려면 코드가 수행하는 새 목록을 작성해야합니다. 효과적으로 말합니다 :

  • 빈 목록을 증가시킨 결과가 빈 목록입니다.
  • 비어 있지 않은리스트를 증가의 결과는 다음과 같습니다
    • 목록의 첫 번째 요소를 가지고 : H.
    • 나머지 목록을 증가 시키십시오 : increment(T).
    • 나머지 목록을 증가시킨 결과 앞에 H+1 앞에 추가하십시오. 당신은 당신이 얼랑에 목록을 작성하거나 많은 자원을 낭비 끝낼 수있는 방법에 대해주의 할

참고. List Handling User's Guide은 그 사실을 알기에 좋은 장소입니다. 또한이 코드는 "재귀"라는 개념을 사용합니다. 즉, 함수가 자체를 호출합니다. 자바를 포함한 많은 대중적인 언어에서 새로운 재귀 호출은 각각의 새로운 함수 호출이 스택 프레임을 추가하고 스택 프레임에 사용 가능한 메모리 공간이 상대적으로 제한되어 있기 때문에 유용성이 제한적입니다. 얼랭 (Erlang)과 많은 함수 언어는 "꼬리 호출 제거 ​​(tail call elimination)"를 지원합니다.이 기능은 올바르게 작성된 코드가 리소스를 모두 소모하지 않고 무기한 재귀 될 수있게 해주는 기능입니다.

이렇게하면 도움이되기를 바랍니다. 보다 구체적인 질문을 할 수 있다면 더 좋은 대답을 얻을 수 있습니다.