Вот неожиданное (мной) поведение в F #. У меня есть простой класс, который сортирует последовательность:
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
Я написал слегка надуманный модульный тест (в C #), чтобы проверить это:
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 );
}
Seq.sort выполняет сортировку последовательности, и первый вывод верен:
3; 3; 4; 7; 8; 11; 12;
Однако обновление объекта теста (ссылочного типа) приводит к повторной сортировке последовательности:
2; 3; 3; 4; 7; 8; 11;
Я ожидал, что значения в объекте MyQueue теперь будут не отсортированы, так как значение в ссылочном объекте изменилось, но Seq.sort, кажется, был выполнен снова. Я не понимаю, я думал, что целью функционального программирования было избежать побочных эффектов. Почему я получаю такое поведение?