문제

기본값에 대해 질문이 있습니다.=F#의 "(같음) 연산자입니다.사용자 정의 공용체 유형을 비교할 수 있습니다.질문은 ~이야:그것의 복잡성은 무엇입니까?예를 들어 다음 유형을 고려해 보겠습니다.

type Tree<'a> =
  | Nil
  | Leaf of 'a
  | Node of Tree<'a> * Tree<'a>

그리고 다음 나무들:

let a : Tree<int> = Node (Node (Node (Leaf 1, Leaf 2), Node (Leaf 3, Node (Leaf 4, Leaf 5))), Node (Leaf 6, Nil))
let b : Tree<int> = Node (Node (Node (Leaf 1, Leaf 2), Node (Leaf 3, Node (Leaf 4, Leaf 5))), Node (Leaf 6, Nil))
let c : Tree<int> = Node (Node (Node (Leaf 1, Leaf 2), Nil), Node (Node (Leaf 3, Node (Leaf 4, Leaf 5)), Leaf 6))

이 코드는 다음과 같습니다.

printfn "a = b: %b" (a = b)
printfn "a = c: %b" (a = c)
printfn "a = a: %b" (a = a)

다음 출력을 생성합니다.

a = b: true
a = c: false
a = a: true

나는 "a = b" 그리고 "a = c" 비교에는 선형 시간이 걸립니다.하지만 "는 어떻습니까?a = a"?그것이 일정하다면, 다음과 같이 더 복잡한 구조는 어떻습니까?

let d : Tree<int> = Node (a, c)
let e : Tree<int> = Node (a, c)

통째로 통과될까 그리고 이자형 구조인가요, 아니면 '에서 멈출까요?a = a" 그리고 "c = c"?

도움이 되었습니까?

해결책

F#은 구조적 동등성을 사용하지만 기본값은 Equals .NET의 구현에서는 참조 동등성을 사용합니다.이는 일반적인 경우 동등 비교가 다음과 같다는 것을 의미합니다. 에) 어디 N 비교되는 객체 그래프의 필드 수입니다.

보장하고 싶다면 a = a 최적화되어 있으므로 재정의할 수 있습니다. Equals 참조 동등성을 먼저 확인하고 그렇지 않으면 구조적 동등성을 확인합니다.유형에 다음과 같은 주석을 달아야 합니다. [<CustomEquality>].

구조적 평등의 다소 긴 구현을 볼 수 있습니다. github의 F# 소스 코드.통화 계층 구조를 따르려면 다음으로 시작하세요. GenericEqualityObj 1412번 라인에서.

다른 팁

편집하다: 원래 답변이 잘못되었습니다.

일반적인 구현 Equals() .Net에서는 다음과 같이 작동합니다.

  • 두 인스턴스를 참조로 비교합니다.둘 다 동일한 객체를 참조하는 경우 반환 true.
  • 두 인스턴스의 런타임 유형을 비교합니다.다르면 반품하세요 false.
  • 해당 유형의 각 필드가 동일한지 쌍으로 비교합니다.동일하지 않은 경우 반환 false, 그렇지 않으면 반환 true.

어떤 이유로 F#은 첫 번째 단계를 건너뜁니다. 이는 시간 복잡도가 항상 선형임을 의미합니다.

컴파일러는 그것을 알고 있기 때문에 a 그리고 b 동일하며 일부 하위 트리는 c 의 일부 하위 트리와 동일합니다. a, 그리고 그것들이 불변이라는 것도 알고 있습니다. 이론적으로 다음을 만들 수 있습니다. a 그리고 b 동일한 개체를 사용하고 해당 부분의 일부를 재사용합니다. c.런타임은 문자열과 비슷한 작업을 수행합니다. 문자열 인턴.그러나 (디컴파일된 코드에 따르면) 컴파일러는 현재 이 작업을 수행하지 않는 것 같습니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top