2015-03-11 4 views
1

Возможно ли создать ref с преобразователем в Clojure, аналогично созданию chan с преобразователем?Создание рефлексов с преобразователями

т. Е. Когда вы создаете chan с преобразователем, он фильтрует/отображает все входы в выходы.

Я бы предположил, что есть способ создать ref, так что, что бы вы ни установили, он может либо игнорировать, либо изменять входные данные. Возможно ли это сделать?

ответ

2

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

user> (def r (ref 0)) 
#'user/r 
user> (add-watch r :label 
       (fn [label the-ref old-state new-state] 
        (println "adding that little something extra") 
        (if (< old-state 10) (dosync (commute the-ref inc))))) 
#<[email protected]: 0> 
user> (dosync (alter r inc)) 
adding that little something extra 
adding that little something extra 
adding that little something extra 
adding that little something extra 
adding that little something extra 
adding that little something extra 
adding that little something extra 
adding that little something extra 
adding that little something extra 
adding that little something extra 
adding that little something extra 
1 
user> @r 
11 

Вы даже можете применить преобразователь к состоянию атома, если хотите.

1

Это интересная идея, но это неправильный способ по крайней мере по нескольким причинам. Вы бы потерять некоторые отношения вы ожидали бы провести:

(alter r identity) =/= r 

(alter r f)(alter r f) =/= (alter r (comp f f)) 

(alter r f) =/= (ref-set r (f @r)) 

Кроме того, некоторые преобразователи Летучие боковые осуществления, и не имеют никакого бизнеса в dosync блоке. т. е. если вы используете (take n) в качестве преобразователя, то если ваш dosync терпит неудачу, он будет повторять попытку, как если бы он вызывал (take (dec n)), что нарушает требования к корпусу dosync.

Проблема ref позволяет читать и писать как отдельные шаги. Если вместо этого было что-то основополагающее, позволяющее вам «применять» вход в скрытое «состояние» и собирать вывод все за один шаг, последовательно с STM, то с этим было бы работать.

 Смежные вопросы

  • Нет связанных вопросов^_^