Как мне создать двух общих производителей/потребителей с внутренним состоянием в Haskell?
-
20-08-2019 - |
Вопрос
У меня есть агент, который принимает состояния и возвращает действия, сохраняя при этом внутреннее представление о полезности пар состояние/действие.У меня также есть среда, которая принимает действия и возвращает пары состояние/награда.
Мне нужно иметь возможность настроить агент с начальным состоянием, а затем непрерывно переходить от агента - (действие) -> среда - (состояние, вознаграждение) -> агент - (действие) ->...Однако внутренние состояния (которые необходимо обновлять на каждой итерации) должны оставаться конфиденциальными (то есть внутри агента или среды).Это означает, что я не могу просто вызвать среду как функцию внутри агента, используя состояние и действие в качестве аргументов.
Я в некоторой степени новичок в Haskell, поэтому даже не уверен, возможно ли это.
Решение
Два вопроса:
Если агент должен использовать состояние для вычисления действия, то как вы собираетесь сохранить представление состояний в секрете от агента?
Если среда ожидает создания состояния (и награды) за действие, как вы планируете сохранить представление состояний в секрете от среды?
Оба варианта возможны, но каждый из них должен включать в себя некоторую абстракцию для запроса состояний или создания состояний.У меня не очень хорошее впечатление об этом дизайне.
Это помогло бы внести ясность в вопрос
Предоставление сигнатур типов для интересующих функций
Определение того, каким функциям вы хотите представлять состояния нет быть разоблаченным.
P.S.Эти трудности вполне отделимы от Haskell и могут возникнуть независимо от выбора языка реализации (при условии, что язык реализации поддерживает некоторый форма конфиденциальности).
Другие советы
Вам нужно будет решить, какой из агента и среды находится «сверху» — в оставшейся части этого ответа давайте предположим, что это среда сверху вызывает агента, поскольку это, как правило, имеет наибольший смысл.
Вы можете сохранить конфиденциальность представления данных Агента с помощью системы модулей — просто экспортируйте имя типа данных без каких-либо его внутренних компонентов.
module Agent (AgentState, other_stuff) where
в отличие от
module Agent (AgentState(..), other_stuff) where
Если агенту также необходимо передать состояние среды (хотя я не вижу никакой причины, по которой это было бы необходимо, поскольку среда может отслеживать его самостоятельно), тогда сделайте функции агента полиморфными, чтобы их можно было передавать любой тип состояния - тогда среда может передавать все, что пожелает, без раскрытия его представления.
Также должна быть возможность использовать монады состояний для достижения большего контроля над тем, что происходит с состоянием, например, предотвращая дублирование средой состояния, которое дает ей агент, и повторный вызов агента с тем же самым состоянием, но если вы новичок в этом Haskell, вероятно, лучше сначала получить немного опыта без монад.(Не то чтобы монады особенно страшны или что-то в этом роде, но они скрывают от вас детали, поэтому труднее понять, что происходит.)