Не могу понять логи c изменяемой переменной F # внутри тела функции - PullRequest
1 голос
/ 08 апреля 2020

Я изучаю F # и застреваю с понятием mutable ключевого слова.

Пожалуйста, посмотрите следующий пример:

let count =
    let mutable a = 1
    fun () -> a <- a + 1; a

val count: unit -> int

, который увеличивается на 1 каждый раз, когда вызывается с (). Но следующий код не:

let count =
    let mutable a = 1
    a <- a + 1
    a

val count: int

Что всегда 2.

В книге, с которой я учусь, в первом примере говорится: «Инициализация изменяемого значения a выполняется только один раз, когда функция вызывается впервые. "

Когда я начал изучать FP с помощью haskell, то, как он обрабатывал побочные эффекты, как это, полностью сожгло мой мозг, но F # mutable снова разрушает мой мозг, другим способом. В чем разница между двумя фрагментами? И каково истинное значение и условие вышеприведенного предложения об инициализации изменяемого значения?

Ответы [ 2 ]

5 голосов
/ 08 апреля 2020

Ваш второй пример

let count =
    let mutable a = 1
    a <- a + 1
    a

Определяет изменяемую переменную, инициализированную 1, затем присваивает ей новое значение (a + 1) с помощью оператора <- перед возвратом обновленного значения в последней строке , Поскольку a имеет тип int, и он возвращается из функции, тип возвращаемой функции также int.

В первом примере

let count =
    let mutable a = 1
    fun () -> a <- a + 1; a

также объявляется int инициализируется в 1. Однако вместо непосредственного возврата он возвращает функцию, которая закрывается над a. Каждый раз, когда вызывается эта функция, a увеличивается и возвращается обновленное значение. Его можно эквивалентно записать в виде:

let count =
    let mutable a = 1
    let update () =
        a <- a + 1
        a
    update

fun () -> ... определяет лямбда-выражение . Эта версия возвращает функцию с 1 аргументом, отраженную в другом типе возврата unit -> int.

3 голосов
/ 08 апреля 2020

Первый пример count инициализирует изменяемую переменную и возвращает замыкание вокруг этой переменной. Каждый раз, когда вы вызываете это замыкание, переменная увеличивается и возвращается ее новое значение.

Второй пример count - это просто блок инициализации, который устанавливает переменную, увеличивает ее один раз и возвращает ее значение. При повторном обращении к count снова возвращается только вычисленное значение.

...