2011-12-14 3 views
5

작은 erlang 서비스를 작성 중이며 내 유형에 제약 조건을 넣고 싶습니다.erlang에서 -spec 기능을 사용하는 방법

나는 -spec 기능을 찾았으며,이 기능이 특정 유형의 기능에 대한 서명을 '잠그는'방법이라고 생각합니다.

내 예는 함수처럼 될 것이다 :

fib(N) when N < 3 -> 
    1; 
fib(N) -> 
    fib(N-1) + fib(N-2). 

-spec fib_cps(pos_integer()) -> pos_integer(). 

이 방법이어야 올바른 형식을 반환 확인해야합니다 라인을 추가하지만,이 경우 될 것 같지 않습니다. .

fib(N) when N < 3 -> 
    ok; 
fib(N) -> 
    not_ok. 
: 내가 할 수있는 기능을 변경하는 경우에 대한

코드는 여전히 컴파일되고 정상적으로 실행됩니다.

내가 뭘 잘못 알고 있니?

+1

BTW, 당신의 타입 스펙은'-spec fib_cps (pos_integer()) -> pos_integer().'와 같이 보일 것입니다 (빈 괄호에주의하십시오). 그렇지 않으면 Dialyzer는 여러분이 원자'pos_integer'를 의미한다고 생각합니다. – legoscia

답변

11

컴파일러는 이러한 주석을 건너 뜁니다. 하지만 투석기를 사용하여 정적 코드 분석을 할 수 있습니다. 이 도구는 사양 위반에 대해 경고합니다.

+0

그 뜻은 inorder는 컴파일러의 dialyzer 도구 ontop을 실행해야하는 'stable'코드를 보장하기 위해서입니까? 이것은 전체 typechecking 문제를 해결하는 방법입니까? –

+0

@MartinKristiansen 예, 안정적인 생산 코드를 원하면 dialyzer를 실행해야합니다. 어쩌면 모든 빌드가 아니라 주기적으로. 예를 들어, 매일 빌드 시스템을 사용하는 경우이를 통합 할 수 있습니다. – werewindle

1

werewindleanother answer에서 -spec은 서명에 사용되지 않고 분석에만 사용됩니다. 입력 유형을 확인하려면 가드에서 유형에 대한 점검을 포함 할 수 있습니다. 따라서, 귀하의 예를 들어, 당신은 할 수 있습니다 :

fib(N) when is_integer(N), N > 0, N < 3 -> 
    1; 
fib(N) when is_integer(N), N >= 3 -> 
    fib(N-1) + fib(N-2). 

또는 더 관용구, 두 합법적 인 기본 경우가 있기 때문에 :

fib(1) -> 1; 
fib(2) -> 1; 
fib(N) when is_integer(N), N >= 3 -> 
    fib(N-1) + fib(N-2). 

fib(bogus) 또는 fib(0.5) 같은 일을하지 못할 것 또는 심지어 fib(-1). 시도 할 경우 런타임에 badmatch으로 실패합니다.

참고 : guard에서 사용할 수있는 유일한 기능은 런타임에서 허용하는 기본 제공 함수입니다. 대부분은 erlang 모듈에 있습니다.

+0

나는 본다. 그러나 내가 정말로 원했던 것은 ML에서와 같이 일종의 정적 typechecking이다. 의미를 유형을 지정하고 싶습니다 A : = C | D. 그런 다음 메소드에 forinstance (_ -> A) 유형을 정의하십시오. 그런 일을 할 수있는 좋은 동시성 메커니즘을 가진 언어를 알고 있습니까? –

+2

@MartinKristiansen : 투석기는 표준 오류 도구입니다. 그것은 erlang과 함께 제공되며 모든 erlang 프로젝트에서 사용해야합니다. 예, 정적 분석은 컴파일러의 일부가 아니지만 어쨌든 언제든지 원하는대로 수행 할 수 있습니다. C 전 처리기가 컴파일러와 별도의 도구 일 것이라고 상상해보십시오. 그것은 어떻게 든 불쾌 할 것이다. 그러나 ok. – werewindle

관련 문제