2014-04-13 2 views
2

"let"표현식을 사용하여 패턴을 재구성하는 것이 가능하다는 것을 알았습니다. 심지어 함수 선언 인 경우에도 마찬가지입니다. 패턴이 철저하지 않기 때문에let을 사용한 OCaml 패턴 재구성

let [c; f; x] = map (fun _ -> scanf " %f" id) (1--3) in ... 

그러나이 경고를 방출 :

그것은 같은 경우에 매우 유용 할 수있다 실제로, 그것은 실패 할 수 있습니다. 그러나 필자의 경우 패턴이 일치하지 않을 때 의도 한 동작 (입력에 대한 나의 주장이 잘못되었다)입니다. 명령문이 실패해야합니다 (스택이 어떤 지점에서 실패 할 수 있음). 나는 그 경고를 가지고 (! 내가 그들을 해제 전역 싶지 않아) 그래서 매우 성가신 (없고 안전)에 후퇴하도록 강요하고있어 마음에 들지

:

let c, f, x = match (map (fun _ -> scanf " %f" id) (1--3)) with 
| [c; f; x] -> c, f, x 
| _ -> failwith "wrong assertion" 
in ... 

무서운 경고없이 첫 번째 대안의 간결한 구문을 가져 오는 방법이 없습니까? 아니면 본격적인 성명서보다 적은 타이핑을 포함하는 다른 구조입니까?

참고 : 함수를 지정할 수있는 것이 좋을 것이라고 생각합니다. 선언 사이트에서 경고를 내지 않고 합계 유형의 주어진 대안 만 취합니다. 발신자가 자신이 오른쪽 인자를 사용하기 위해, 또는 자신이 경고를 얻을 것입니다 것은 ... 것

날 "foo는 SN"와 같은 서명을 필요로 명확하게하지 않기 때문에
type ast = Id of string | Var of string * int 
let foo (Var(s,n)) = ... 

foo (Var("bar", 42)) (* ok *) 
foo (Id "bar")  (* warning; or even error *) 

(이다 foo는이 바르 - 건설 AST의 데이터를 사용하기위한 것입니다) 당신은 변형 유형을 사용할 수

+0

을, 가능하다면'ast '로부터'(s, n)'을 얻는 것은 호출자의 몫입니다. –

+0

예, 그렇다고해서 문제가 해결되지 않습니다. 예를 들어, 다른 대안 (또는 심지어 유형)이 동일한 서명을 갖는다면 어떨까요? –

+1

유형 수준 보증이 아닌 경고를 선택적으로 해제하고 싶을 수도 있습니다. 최선의 방법은'let' 파생 형식을'failwith' 분기로 패턴 매칭으로 변환하는 구문 확장을 작성하는 것입니다. – lukstafi

답변

2

:.`당신은`정의 foo는 (S, N) = ...을 할 수

type ast = [`Id of string | `Var of string * int] 

let foo (`Var (s, n)) = (s, n) 
(* val foo : [< `Var of 'a * 'b ] -> 'a * 'b *) 

foo (`Var("bar", 42)) (* : string * int = ("bar", 42) *) 
foo (`Id "bar") (* Error: This expression has type [> `Id of string ] *) 
+0

그렇지만 합계 유형의 오브젝트를 사용하여 변형 된 foo를 정의 할 때 foo를 호출 할 수 없다는 것은 유감스러운 일입니다./ –

+0

@LP_ 의존형이 없으면 정말 부탁하는 것은 불가능합니다. 가장 가까운 타입은 variant 타입을 사용하는 것입니다. 그러나 OCaml 타입 시스템은 여러분이 사용할 수있는 양을 제한합니다. 'Var ("foo", 42)의 타입은 실제로'ast'이고, OCaml 타입 체커의 정적 분석은 감히 그걸 질문하지 않습니다. –