Осколок Haskell STM TVAR

Я новичок в Haskell и STM, и я пытаюсь понять основную концепцию.

В Haskell и функциональном программировании в целом, поправьте меня, если я ошибаюсь, нет такой вещи, как присваивание.

Я не могу написать x=3;, все, что я могу сделать, это сгенерировать другую привязку с x и 3.

Теперь, когда дело доходит до TVar и потоков, если у меня есть несколько потоков, использующих один и тот же TVar, если один поток изменит значение с помощью writeTVar, другие потоки увидят измененное значение, я прав?

Итак, если у меня есть 2 потока, разделяющих одну и ту же переменную TVar Int, и первый добавляет к ней 1, в случае успеха второй поток увидит обновленное значение?

Такс


person user1544128    schedule 05.01.2013    source источник


Ответы (2)


Возможно, лучше рассматривать TVar не как переменную, а как канал, из которого вы можете читать и писать.

Чистую переменную можно считать чистой функцией, которая всегда возвращает некоторое значение (и это значение привязывается только один раз, как в вашем примере). Переменная/функция в монаде имеет некоторый «контекст» (для этого и нужны монады), который может изменить свое значение (например, randomIO :: Random a => IO a из System.Random может считаться «монадным значением», значением, которое может быть изменено при любом вызове).

Чтение и запись в TVar являются явными операциями, которые не являются чистыми, поэтому функции readTVar/writeTVar завернуты в монаду STM, они зависят от некоторого скрытого контекста, который может изменить результат (делая возможным передачу значений между потоками). Однако это связывает эти операции в монаду STM, которую можно экранировать только в IO.

person Dmytro Sirenko    schedule 05.01.2013
comment
Спасибо, это многое проясняет :) - person user1544128; 05.01.2013

Да, TVar — это контейнер, который не меняется при изменении его содержимого. Все потоки видят один и тот же контейнер, и когда один поток изменяет то, что было сохранено в контейнере, когда другой поток смотрит, он находит измененное значение.

person Daniel Fischer    schedule 05.01.2013
comment
Хорошо, спасибо за подтверждение, просто сначала это выглядело немного странно. - person user1544128; 05.01.2013
comment
просто небольшой дополнительный вопрос, если можно: когда я создаю поток с forkIO, поскольку возвращаемое значение является IOThread, единственный способ получить результаты, рассчитанные потоком, - это сделать запись потока в TVar и основное чтение от него? - person user1544128; 05.01.2013
comment
Это не обязательно должен быть TVar, вы также можете использовать TChan, Chan, MVar, IORef и, возможно, больше. Но принцип действительно таков: если вы хотите общаться с потоком forkIOd, вам нужна какая-то коммуникационная переменная. - person Daniel Fischer; 05.01.2013