2010-04-21 2 views
5

F #에서 항등 연산자 (=)는 일반적으로 intensional이 아닌 extensional입니다. 멋지다! 불행히도, F #은 이러한 확장 비교를 단축하기 위해 포인터 평등을 사용하지 않습니다. 예를 들어F #의 짧은 절단 동등 검사?

,이 코드 :

 
type Z = MT | NMT of Z ref 

// create a Z: 
let a = ref MT 
// make it point to itself: 
a := NMT a 

// check to see whether it's equal to itself: 
printf "a = a: %A\n" (a = a) 

... 나에게 큰 지방 세그먼트 오류를 ​​준다 [*], 사실에도 불구하고 그 'A'와 'A'모두 동일한 기준으로 평가한다. 별로 좋지 않습니다. 포인터 비교를 사용하여 포인터를 비교하여 결정할 수있는 경우 다른 함수 언어 (예 : PLT Scheme)가 포인터 비교를 사용하여 'true'를 반환합니다.

그래서 : F #의 항등 연산자가 짧은 커팅을 사용하지 않는다는 사실을 받아 들일 것입니다. intensional (포인터 기반) 동등성 검사를 수행 할 수있는 방법이 있습니까? 내 타입에 (==) 연산자가 정의되어 있지 않고 누군가가 어떻게 든 사용할 수 있다고 말할 수 있다면 그것을 좋아할 것입니다.

아니면 상황의 내 분석 틀렸다 말해 : 내가 사랑하는 것, 너무 ...

[*] 그건 아마도 Windows에서 스택 오버 플로우 될 것이다; Mono에 관한 것들이 내가 좋아하는 것이 아닙니다 ...

답변

7

내가 알고있는 두 가지 옵션이 있습니다. 표준 .NET 방식은 System.Object.ReferenceEquals을 사용하는 것입니다. F #에서 약간 더 나은 접근 방식은 기본적으로 동일하지만 참조 유형에서만 작동하며 (두 가지 인수가 동일한 정적 유형을 갖기 위해 필요함) LanguagePrimitives.PhysicalEquality을 사용하는 것일 수 있습니다. 더 멋진 구문을 원하면 이러한 함수 중 하나의 측면에서 원하는 사용자 정의 연산자를 정의 할 수도 있습니다.

제쳐두고 .NET에서 나는 꼬리 호출 최적화로 인해 코드를 실행할 때 무한 루프가 발생하지만 스택 오버 플로우는 발생하지 않습니다.

+0

고마워요! 옆으로 : 그렇습니다, 이것은 실제로 mono/osx에 코어를 버립니다. 아마도 꼬리 호출은 내가 사용하고있는 mono/fsharp의 특정 조합에서 동등한 검사를 위해 적절히 구현되지 않을 수도 있습니다. –