Почему набор предметов не работает должным образом?

type dMatrix with
    member t.Item
        with get(a: int, b: int) = t.dArray.[b+a*t.num_cols |> SizeT]
        and set(a: int, b: int) (value: floatType) = t.dArray.[b+a*t.num_cols |> SizeT] <- value
    member t.setItem(a: int, b: int) (value: floatType) = t.dArray.[b+a*t.num_cols |> SizeT] <- value

let a = dMatrix.createRandomUniformMatrix n m 50.f 50.0f

a.[1,1] <- 654.0f // Gives 'A value must be mutable in order to mutate the contents or take the address of a value type, e.g. 'let mutable x = ...''
a.setItem(1,1) 654.0f // Works fine.

Я не уверен, что происходит в вышеупомянутом. dArray имеет тип CudaDeviceVariable<float32> из библиотеки ManagedCuda, если это поможет.

Редактировать:

type dMatrix = 
    struct
        val num_rows:int
        val num_cols:int
        val dArray: CudaDeviceVariable<floatType>

Вот как выглядит структура выше. Даже если я сделаю изменяемый dArray, он все равно не работает, но пишет что-то вроде a.dArray.[SizeT 0] <- 2.5f делает. Есть ли обходной путь для этого?

Edit2: Превращение вышеупомянутого в запись или класс решает проблему.

1 ответ

Решение

Сообщение об ошибке очень полезно здесь. В F# значения неизменяемы по умолчанию. Изменчивость должна быть объявлена ​​в явном виде, см.: https://msdn.microsoft.com/en-us/library/dd233185.aspx

Если вы хотите сделать a изменяемый, сделать:

let mutable a = dMatrix.createRandomUniformMatrix n m 50.f 50.0f

Обычно не требуется что-то делать mutable если вы не хотите изменить само значение (в отличие от изменения одного из членов этого объекта), это поведение будет различным для значений и ссылочных типов, например, это скомпилирует:

let a = [|5; 10; 9; 3; 2|]
a.[2] <- 6

Но если бы были a структура с индексатором, это не будет. Например, эта структура производит точно такое же поведение, которое вы описываете:

type TestStruct =
    struct 
        val mutable Xs : int[]
    end

    member this.Item
        with get(i) = this.Xs.[i]
        and set(i : int) (value) = this.Xs.[i] <- value

    member this.SetValue i y =
        this.Xs.[i] <- y

Итак, я предполагаю, что у вас есть вовлеченные типы значений.

Другие вопросы по тегам