2017-05-10 4 views
0

특정 유형이 될 것이다 "약속"에 : 그것은 입력 "empty" 인의 경우 임의의 색상을 반환어떻게 값은 내가 입력 된/라켓에이 기능이있는 경우

(: random-if-empty (-> (U Image-Color "empty") Image-Color)) 
(define (random-if-empty s) 
    (cond 
    [(equal? s "empty") (random-color)] 
    [else s])) 

를, 그렇지 않으면 그것은 입력의 반환 형식 검사기에서 대신 Image-Color또는"empty"이 될 수 있다고 s (in in [else s])이 말하지 않도록하려면 어떻게해야합니까? 아니면 전체적으로 더 좋은 방법이 있습니까? 나는 typed/2htdp/image 라이브러리를 사용하고 있는데, Image-Color의 출처입니다.

답변

0

술어는 변수가 특정 값이거나 그렇지 않은 것으로 유형 시스템에 알릴 수 있지만 특정 유형의 특정 값에만 적용됩니다. 간단한 유형 (부울, 기호, 빈 목록, void 및 01)에서 작동하지만 문자열을 비롯한 대부분의 다른 데이터 형식에서는 작동하지 않습니다.

(이 문자열은 변경할 수있는 함께 할 수있는 뭔가가있을 수 있습니다, 나는 확실하지 않다.)

이이 "empty" 문자열에 대한 자신의 술어 다른 방법을 확인하는 것입니다 해결하는 방법. 입력 된 라켓은 양식을 제공합니다 make-predicate 어떤 간단한 "플랫"유형을 술어로 바꿀 수 있습니다.

(define my-empty-pred? (make-predicate "empty")) 

이 새로운 술어가 (my-empty-pred? x) true를 반환하는 경우, 다음 x이 유형 "empty"을 가지고있는 타입 시스템에게보다 직접적으로 occurrence typing을 사용할 수 있습니다, 그것은 다음 x false를 반환하는 경우 : 당신은 다음과 같이 사용할 수 있습니다 님의 유형은 "empty"이 아니어야합니다. 예를 들어 다음과 같이 사용할 수 있습니다.

(: random-if-empty (-> (U Image-Color "empty") Image-Color)) 
(define (random-if-empty s) 
    (cond 
    [(my-empty-pred? s) (random-color)] 
    [else s])) 
0

occurrence typing을 사용하여 두 번째 경우의 s이 문자열 일 수 없다는 것을 유형 검사기에 알릴 수 있습니다.

#lang typed/racket 

(require typed/2htdp/image) 

(define (random-color) : Image-Color 
    (color 0 0 0)) ;; dummy 

(: random-if-empty (-> (U Image-Color "empty") Image-Color)) 
(define (random-if-empty s) 
    (cond 
    [(string? s) (random-color)] 
    [else s])) 

이유는 string? 일과하지 (equal? s "empty)"합니까? 나도 몰라, Typed Racket이 똑똑하지 않다고 생각해. 당신의 유형은 정말 그냥 주장처럼 기록되는, casting에 의존해야 할 수도 복잡 할 경우

또한 assertions

(: random-if-empty (-> (U Image-Color "empty") Image-Color)) 
(define (random-if-empty s) 
    (cond 
    [(equal? s "empty") (random-color)] 
    [else (assert s string?)])) 

를 사용할 수 있습니다. 하지만 나는 이러한 솔루션을 선호도 순으로 제공했습니다. 주조는 최후의 수단이어야합니다.

+0

동등하지 않습니다. 그것은 술어가 아니기 때문입니다. – Vityou

+0

'string? '으로 변경하면 Image-Color가 문자열 일 수있는 경우 프로그램의 동작이 변경됩니다. 'typed/2htdp/image'에서 가능하기 때문에, Gibstick의 첫 번째 해결책은 잘못되었습니다. –

관련 문제