如何在Haskell中创建具有内部状态的两个相互生产者/消费者?

如何在Haskell中创建具有内部状态的两个相互生产者/消费者?,haskell,artificial-intelligence,abstraction,modularity,agent,Haskell,Artificial Intelligence,Abstraction,Modularity,Agent,我有一个代理,它接收状态并返回动作,同时保持状态/动作对效用的内部表示。我还拥有一个环境,可以采取行动并返回状态/奖励对 我需要能够将代理设置为启动状态,然后从代理-(操作)->环境-(状态,奖励)->代理-(操作)->。。。 但是,内部状态(每次迭代都需要更新)需要保持私有(即,在代理或环境中)。这意味着我不能简单地使用状态和操作作为参数在代理中调用环境作为函数 我有点像Haskell noobie,所以我甚至不确定这是否可行。您需要决定哪个代理和环境位于“顶部”-让我们假设在本回答的其余部分

我有一个代理,它接收状态并返回动作,同时保持状态/动作对效用的内部表示。我还拥有一个环境,可以采取行动并返回状态/奖励对

我需要能够将代理设置为启动状态,然后从代理-(操作)->环境-(状态,奖励)->代理-(操作)->。。。 但是,内部状态(每次迭代都需要更新)需要保持私有(即,在代理或环境中)。这意味着我不能简单地使用状态和操作作为参数在代理中调用环境作为函数


我有点像Haskell noobie,所以我甚至不确定这是否可行。

您需要决定哪个代理和环境位于“顶部”-让我们假设在本回答的其余部分,是顶部环境调用代理,因为这通常最有意义

您可以使用模块系统将代理的数据表示形式保持为私有—只需导出数据类型名称,而不导出其任何内部内容

module Agent (AgentState, other_stuff) where
反对

module Agent (AgentState(..), other_stuff) where
如果代理还需要传递环境的状态(尽管我看不出有任何必要这样做的原因,因为环境可以自己跟踪它),然后使代理函数具有多态性,以便可以传递任何状态类型-然后环境可以在不公开其表示的情况下传递它喜欢的任何内容

还可以使用状态单子来实现对状态的更多控制,例如防止环境复制代理给它的状态,并使用相同的状态重复调用代理,但是如果您是Haskell的新手,最好先获得一点没有单子的经验。(并不是说单子特别吓人或是其他什么,但它们确实对你隐瞒了细节,所以很难看到发生了什么。)

两个问题:

  • 如果代理必须使用一个状态来计算一个动作,那么您希望如何对代理保密状态的表示

  • 如果环境希望通过一个动作产生一个状态(和一个奖励),那么您希望如何对环境保密状态的表示

这两种方法都是可能的,但每种方法都必须涉及某种用于查询状态或创建状态的抽象。我对这个设计感觉不太好

这将有助于通过以下方式澄清问题:

  • 为感兴趣的函数提供类型签名

  • 确定不希望状态表示公开给哪些函数


注意:这些困难与Haskell是完全不同的,无论选择何种实现语言(前提是实现语言支持某种形式的隐私)。

如果我可以从代理内部将环境作为函数调用,那么代理可以有一个类似代理的类型::(action->percept)->代理状态->感知->结果。如果环境(action->percept)可以更新它自己的内部状态表示,那么我认为这会起作用。我尝试的另一种可能性是使环境成为一个闭包,返回一个percept和另一个闭包。不幸的是,这将有一个无限类型(percept,(action->)(percept,(action->(percept…现在我正在使用一个单独的函数来调用这两个函数并保留它们的参数。在Haskell中可以有无限类型,只要你用数据构造函数切割每个周期。发布你想要的类型和签名,我可能会帮上忙。很好,我想我现在已经找到了。我定义了以下类型:data percept=percept状态奖励(Environment)和数据环境=环境(Action->Percept)。它似乎工作得很好。我明白了,所以方法是让一个模块完全访问另一个模块,而不知道其内部结构?您正在导出代理类型,但不导出有关该类型实例的外观或存储内容的任何信息。