2012-03-15 4 views
1

2 개의 매개 변수를 사용하여 bool을 반환하는 표준 ML에서 함수를 만들려고합니다. 그리고 2 개의 매개 변수는 어떤 형식이든간에 'a * 'a -> bool으로 작성되었지만 시도 할 때마다 2 개의 매개 변수를 만듭니다. 자동으로 ints. 어떻게 함수가 'a 형의 2 개의 매개 변수를 취하게 할 수 있습니까?표준 ML에서 'a *'a -> bool 유형의 함수를 어떻게 정의 할 수 있습니까?

fun lessThan (a, b) = 
    if a < b then true 
    else false; 

을하지만, 위의 함수를 작성 후 내가 얻을 것은 :

val lessThan = fn : int * int -> bool 

와 내가 원하는 것은 이것이다 :

다음

기능 필자 구현하기 위해 노력하고있다

val lessThan = fn : 'a * 'a -> bool 

어떻게 작동합니까?

답변

6

함수를 종료하고 값을 반환하려면 표준 ML에 'a * 'a -> bool 유형의 함수가 두 개 있습니다. 그들은

fun ktrue (_, _) = true 
fun kfalse (_, _) = false 

다른 모든 총, 해당 유형의 순수 기능은 위의 두에서 구별 할 수 있습니다.

그리고이 두 함수는 실제로보다 일반적인 유형 'a * 'b -> bool입니다.

이것은 실제로 프로그래밍 언어 이론의 결과입니다. 기초를 배우고 싶다면 John Reynolds의 표현 독립성 또는 Phil Wadler의 "자유 이론"에 대한 연구를 읽어 볼 수 있습니다.

+1

좋은 설명과 (분명히) 아름다운 종이,하지만 OP의 질문에 대해서는 문제가 전적으로 int에 정의 된 연산자와 관련이 있다고 생각합니다. (이 반응이 어떤 생각에 도움이되지 않는다고 말하는 것은 아닙니다!) –

+1

그런데, 당신이 그것을 언급 한 경우 (@aizen), Ramsey 박사의 참고 문헌은 "Theorems for free"이며, 누구에게나 정말 멋진 책! –

0

저는 이것이 SML의 펑터로 해결할 수있는 문제라고 생각합니다.

예를 들어 질문에서 사용자의 기능을 정의하는 TOTALORDER라는 서명이 있다고 가정합니다 (보다 낮은 의미).

signature TOTALORDER = 
sig 
    type element 
    val lt: element * element -> bool 
end 

당신은 함수가 element * element -> bool로 정의하고, 요소의 유형이 여기에 정의되어 있지 볼 수 있듯이. 다음과 같이

우리는 그 다음 다른 유형의 작업을 TOTALORDER의 두 가지 구현을 정의 할 수 있습니다

structure String : TOTALORDER = 
struct 
    type element = string 
    fun lt(a:string, b) = a < b 
end 

structure Integer: TOTALORDER = 
struct 
    type element = int 
    fun lt(a, b) = a < b 
end 

을 우리가 작업 문자열 할 수있는 구현 및 정수 작업 할 수있는 또 다른 하나를 정의 위. 이 구현에서 실제 유형이 element 인 것을 정의 할 수 있습니다. 이제

다음과 같이 우리가 펑터의 교환 종류의 마법을 정의 할 수 있습니다 :

functor MakeComparator(Lt: TOTALORDER): 
    sig 
     val descending : Lt.element * Lt.element -> Lt.element * Lt.element 
     val ascending : Lt.element * Lt.element -> Lt.element * Lt.element 
    end 
    = 
    struct 
     open Lt; 

     fun descending(a,b) = if lt(a,b) then (b,a) else (a,b) 
     fun ascending(a,b) = if lt(a,b) then (a,b) else (b,a) 
    end 

을 그리고 여기에 우리가 펑 우리의 TOTALORDER에 따라 상승과 하강이라는 두 가지 기능으로 서명을 정의하는 것을 볼 수있다 정의. 펑터는 이러한 서명의 구현을 매개 변수로받습니다. 그리고 나중에 그것을 struc 구현에서 사용하여 쌍을 오름차순 또는 내림차순으로 정렬합니다.

궁극적으로, a 및 b 유형은 펑터에 제공된 TOTALORDER 구현의 요소 유형에 따라 달라집니다.

structure StringComparator = MakeComparator(String) 
structure IntegerComparator = MakeComparator(Integer) 

을 우리는 자신의 유형과 대응을 사용할 수 있습니다

이제 우리는 다음과 같이 서로 다른 비교 유형을 사용하여 서로 다른 구현을 만들 수 있습니다. 예를 들어 :

val res01 = StringComparator.ascending("arm","house") (*(arm,house)*) 
val res02 = StringComparator.descending("arm","house") (*(house,arm)*) 
val res03 = IntegerComparator.ascending(1,2) (*(1,2)*) 
val res04 = IntegerComparator.descending(1,2) (*(2,1)*) 

그것은 타입 클래스와 하스켈 같은 다른 언어에 비해 확실히 자세한하지만 나는 그것이 문제를 해결하는 올바른 방법입니다 생각합니다.