다음은 F #의 예상치 못한 (나에 의한) 동작입니다. 나는 순서 정렬 간단한 클래스가 다음 Seq.sort 정렬 순서를 수행F # Seq.sort가 입력 시퀀스의 복사본을 반환합니까?
private class TestObject : IComparable
{
public TestObject(double Value)
{
this.Value = Value;
}
public void Update(double NewValue)
{
this.Value = NewValue;
}
public double Value { get ; private set; }
public int CompareTo(object Comparable)
{
return this.Value.CompareTo((Comparable as TestObject).Value);
}
public override string ToString()
{
return Value.ToString();
}
}
[Test]
public void TestUpdate_OK()
{
var nums = new double[]{7,4,3,12,11,3,8};
var values = nums.Select(n => new TestObject(n)).ToArray();
var q = new MyQueue<TestObject>(values);
Console.WriteLine (q.ToString());
// update one of the values in the collection - should not re-sort the collection
values[3].Update(2.0);
Console.WriteLine (q.ToString());
Assert.AreEqual(q.First.Value, 3.0);
}
, 그리고 : 나는 (C#으로) 약간 인위적인 단위 테스트를 작성했습니다
type MyQueue<'a when 'a : comparison> (values : 'a[]) =
let vals =
Seq.sort values
member this.First = Seq.nth 0 vals
override this.ToString() =
Seq.fold (fun s a -> s + a.ToString() + ";") "" vals
을 테스트하려면 첫 번째 출력은 올바른 것입니다 :
3; 3; 4; 7; 8; 11; 12;
그러나, 테스트를 갱신 (참조 타입) 오브젝트는 순서 재정렬되게 :
2, 3, 3, 4, 7; 8; 11;
나는 참조 개체의 값이 변경 이후 MyQueue 인 객체의 발스 지금, 분류되지 않은 것이라고 예상하지만, Seq.sort 다시 수행 된 것으로 나타납니다. 나는 이해하지 못한다. 나는 함수형 프로그래밍의 목적이 부작용을 피하는 것이라고 생각했다. 왜 이런 행동을합니까?
이것이 내가 이해하지 못하는 것의 핵심이라고 생각합니다. 내 단위 테스트에는 2 개의 ToString()이 있습니다. 나는 그 종류가 처음에 일어날 것으로 예상했을 것이다. 따라서 첫 번째 ToString()은 예상대로 정렬됩니다. 그러나 두 번째 출력도 다시 정렬되며 어디에서 오는 것인지 이해할 수 없습니다. – Aidan
그리고 그것은 FP가 아니라는 것에 동의하지만, F #을 순수하게 기능화하기 위해 expcet하지 않습니다. 그러나 나는 그 명령문이 vals = Seq.sort 값을 기능적으로 동작하도록 할 것을 기대했다. – Aidan
ToString을 호출 할 때 정렬이 일어나기 때문에 ToString을 호출 할 때마다 기본 배열이 정렬되고이 정렬 된 배열의 문자열 표현이 반환된다. 경우에 u는 'let vals = Array'를 만든다.정렬 값 '이면 정렬은 객체가 만들어 질 때만 발생하며 toString은 Array.sort가 새로운 정렬 된 배열을 만들 때 원래 배열 객체의 수정과 관계없이 항상 동일한 결과를 반환합니다. – Ankur