python - 如何为类似状态单子的事物定义平面图
问题描述
我正在尝试解决如何flatmap
为我的状态单子定义的东西。
class State(Protocol[T_co]):
@abstractmethod
def __call__(self: S, i: int) -> tuple[T_co, S]:
...
AState
封装了状态。这里是unit
def unit(t: T) -> State[T]:
return lambda _: (t, unit(t))
我从他们使用的一本书中得到了设计,State[S, A] = S -> (A, S)
但我发现这有点麻烦(并且还需要额外的参数i
),所以这里 aclass Foo(State[int])
几乎就像 a State[Foo, int]
。我想知道我简化它的尝试是否已经阻止它成为一个单子。
我尝试了类似的东西
def flatmap(f: Callable[[T], State[U]], s: State[T]) -> State[U]:
def stateful(i: int) -> tuple[U, State[U]]:
t, s_new = s(i)
u, su = f(t)(i)
return u, flatmap(f, s_new) # or u, su
return stateful
但尽管我认为这满足身份(尚未检查关联性),但我希望同时使用新状态s_new
和su
.
为了完整起见,这里有一个恐怖,它是flatmap
从用于我的案例的书中的字面翻译S -> (A, S)
,带有一个额外的论点i: int
。我对它会起作用的期望为零
def flatmap(f: Callable[[T], State[U]], s: State[T]) -> State[U]:
class _State(State[U]):
def __call__(self, i: int) -> tuple[U, _State]:
x, y = type(s).__call__(self, i)
return type(f(x)).__call__(y, i)
return _State()
解决方案
我认为这是不可能的。状态的标准定义使用S -> (A, S)
. 添加一个额外的参数(S, int) -> (A, S)
可能会或可能不会破坏它,但可能会是这样一个事实,即 a(S, int) -> (A, S)
可以接受任何东西作为它的第一个参数,而 (a subclass of)class State
的实例只能接受该类的实例作为self
. 也就是说,我将自己限制在一个State
只能接受自己作为第一个论点的范围内。这究竟是如何排除定义flatmap
我仍在努力解决的。
推荐阅读
- javascript - 垫子步进器不适用于选择选项
- visual-studio - 如何在运行时根据地址确定 C++ 对象的类型?
- javascript - 在 Phaser 3 TypeError 中调用 this.scene.restart(): this.body is undefined
- html - 无法获取表格单元格值
- java - 打开 url 并发送标头值
- javascript - 为什么 lodash deepClone 不对 Function 属性进行深度克隆?
- java - 使用 thymleaf 将整数中的美分值转换为 HTML 中的货币
- python - 拼字游戏:假设您正在尝试完成填字游戏
- javascript - 我需要反转对象的格式
- mysql - 在 laravel 5.8 中连接到第二个数据库时出错