2017-10-20 11 views
0

모든 유형의 목록을 취하고 목록이 실제 목록 인 경우에만 head 요소를 반환하는 샘플 함수를 작성하려고합니다.ML 목록 유형을 확인하고 오류 메시지를주는 방법은 무엇입니까?

그렇지 않으면 함수에서 오류 메시지

을 제공해야합니다. . . 연산자 : 연산자와 피연산자가 없습니다. . .

datatype typeR = Real of real 
fun head(xs) = 
    case xs of 
     [] => raise List.Empty | 
      Real (x::_) => x:real ; 

답변

1
(fn x:real list => hd x) [ 4 ,5 ]; 
out> error: Type error in function application 
(fn x:real list => hd x) [ 4.0 ,5.0 ]; 
out> it = 4.0: real 
+4

코드 설명을 추가하십시오. –

+0

'(fn x : 실제 목록 => hd x)'는 모든 유형의 목록을 취하지 않고 * 단지 실제 목록 만 취합니다. 그러나 목록이 실제 값 목록 인 경우에만 head 요소를 반환하고 * reals 목록에 속하지 않을 때 형식 오류를 생성합니다. 또는'hd : real list -> real'. –

2

그것의 전적으로 분명 당신이 계신 - 당신은 "모든 유형"을 소요하고 매개 변수 유형을 검사하는 기능을 쓸 수 없습니다.
가 (유형 약어하지 않고, head(xs) 작성, head 모든 유형을받는 함수를하지 않습니다. 그것의 유형을 추론한다.)

을 당신이 당신의 주요 실수는 당신이 작성해야 Real (x::_)을하는 기능 typeR list -> real 작성하고 싶은 경우 (Real x) :: _. 인
,

fun head(xs) = 
    case xs of 
     [] => raise List.Empty 
    | (Real x)::_ => x 

또는보다 관용구,

fun head [] = raise List.Empty 
    | head (Real x :: _) = x 
0

우선 어떤 피드백 :

  • 단지 그 수의 마진을 허용 때문에이 함수는 실패하는 경향 입력. 가능한 경우 총 기능을 작성하십시오.

  • raise Empty은 목록이 비어 있지 않지만 첫 번째 요소에는 실제가 포함되지 않은 상황을 설명하지 않습니다. 그런 다음 또 다른 예외를 제기해야합니다.

  • 다음 요구 사항은 매우 의심 스럽습니다.

    그렇지 않으면 함수는 오류 메시지

    에게 제공해야합니다. . . 연산자 : 연산자와 피연산자가 없습니다. . .

    런타임 예외와 컴파일 타임 오류를 구별하지 말 것을 제안합니다. 이것은 프로그램 시작 후 오류 및 예외가 모두 처리되는 동적 유형 언어의 프로그래밍 경험에 대해 증상이 있습니다. 이어서

아이디어 : 표준 ML에

목록은 편집 만의 유형 검사 단계에서 판별 한 번에 하나 개의 형태 일 수 있음을 의미 균질하다. 이 문제를 해결하고 더 동적 인 타이핑을 할 수있는 몇 가지 방법이 있습니다.

  • Using algebraic data types [wiki.haskell.조직] :

    datatype dynamic = R of real 
           | I of int 
           | B of bool 
           | S of string 
    fun headR [] = raise Empty 
        | headR (R r :: _) = r 
        | headR _ = raise Domain 
    

    그런 다음 headR 실제로 어떤 유형을 허용하지 않습니다. 임의의 타입의 파라미터를 가지는 임의의 고정량의 값 생성자를 보관 유지할 수있는 정확하게 1 개 (dynamic)를 받아들입니다.

    val foos = [R 42.0, I 10, B true, S "Hello, World!"] 
    
  • Using exceptions [informallyabstract.blogspot.com] : 이것은 이종리스트 모방

    datatype dynamic = Dynamic of exn 
    exception IsReal of real 
    fun wrap_real r = Dynamic (IsReal r) 
    fun unwrap_real (Dynamic ex) = raise ex handle IsReal r => r 
    fun headR (d::_) = unwrap_real 
        | headR [] = raise Empty 
    

    그럼 headR 마찬가지로 만 수락 하나 유형 dynamic를 대신 사용한 것을 어떤 예외 실패 래퍼의 real

    exception IsString of string 
    fun wrap_string r = Dynamic (IsString r) 
    fun unwrap_string (Dynamic ex) = raise ex handle IsString r => r 
    val foos = [wrap_real 42.0, wrap_string "This didn't exist before."] 
    

나도 그들이 런타임 오류의 불필요한 위험을 소개하기 때문에 바람직하다 : 예외 및 일반 datatype 정의를 사용 사이의 차이는 예외가 나중에 새로운 생성자로 확장 할 수 없습니다.