저는 이것이 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)*)
그것은 타입 클래스와 하스켈 같은 다른 언어에 비해 확실히 자세한하지만 나는 그것이 문제를 해결하는 올바른 방법입니다 생각합니다.
좋은 설명과 (분명히) 아름다운 종이,하지만 OP의 질문에 대해서는 문제가 전적으로 int에 정의 된 연산자와 관련이 있다고 생각합니다. (이 반응이 어떤 생각에 도움이되지 않는다고 말하는 것은 아닙니다!) –
그런데, 당신이 그것을 언급 한 경우 (@aizen), Ramsey 박사의 참고 문헌은 "Theorems for free"이며, 누구에게나 정말 멋진 책! –