函数中的类型安全状态处理

发布于 2024-10-15 16:25:23 字数 1047 浏览 0 评论 0原文

所以我想要有一堆接收状态并返回新状态结果的函数。本质上是状态单子,但没有单子方法。与状态单子不同,状态不应该在函数之间流动,而是调用函数,返回结果和状态,并且状态被保存到下一次调用函数为止。所以我有一个函数列表和一个状态列表(每个函数都有不同的状态类型),我想用其状态调用每个函数并更新状态列表。

我的问题是如果不进行强制转换就无法使其工作。

这是一个 REPL 会话:

scala> type StateM[T] = T => (Int, T)
defined type alias StateM

scala> val c: StateM[Int] = {i => (i, i + 1)}
c: (Int) => (Int, Int) = <function1>

scala> val a: StateM[_] = c
a: StateM[_] = <function1>

scala> val z: Any = 0
z: Any = 0

scala> a(z)
<console>:19: error: type mismatch;
 found   : z.type (with underlying type Any)
 required: _$1 where type _$1
       a(z)
         ^

更新:我认为存在类型可能会有所帮助。像这样的东西:

scala> type StateT = Pair[StateM[X], X] forSome {type X}
defined type alias StateT

scala> val t: StateT = (c, 0)
t: StateT = (<function1>,0)

scala> t._1(t._2)
<console>:13: error: type mismatch;
 found   : t._2.type (with underlying type Any)
 required: X where type X
       t._1(t._2)
              ^

So I want to have a bunch of functions that receive a state and return a result with a new state. In essence, the state monad, but without the monadic methods. Unlike the state monad, the state is not supposed to flow between the functions, rather, a function is called, returns a result and state and the state is saved until the next time the function is called. So I have a List of functions and a list of states (each function has a different state type) and I want to call each function with its state and update the list of states.

My problem is that I can't make it work without casting.

Here's a REPL session:

scala> type StateM[T] = T => (Int, T)
defined type alias StateM

scala> val c: StateM[Int] = {i => (i, i + 1)}
c: (Int) => (Int, Int) = <function1>

scala> val a: StateM[_] = c
a: StateM[_] = <function1>

scala> val z: Any = 0
z: Any = 0

scala> a(z)
<console>:19: error: type mismatch;
 found   : z.type (with underlying type Any)
 required: _$1 where type _$1
       a(z)
         ^

UPDATE: I thought that maybe existential types would help. Something like:

scala> type StateT = Pair[StateM[X], X] forSome {type X}
defined type alias StateT

scala> val t: StateT = (c, 0)
t: StateT = (<function1>,0)

scala> t._1(t._2)
<console>:13: error: type mismatch;
 found   : t._2.type (with underlying type Any)
 required: X where type X
       t._1(t._2)
              ^

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

ゃ懵逼小萝莉 2024-10-22 16:25:23

所以我找到的解决方案是使用一个包装两者的类:

scala> case class StateWithVal[T](f: StateM[T], v: T) {def apply() = StateWithVal(f, f(v)._2)}
defined class StateWithVal

scala> val sv:StateWithVal[_] = StateWithVal(c, 0)
sv: StateWithVal[_] = StateWithVal(<function1>,0)

scala> sv()
res15: StateWithVal[_] = StateWithVal(<function1>,1)

So the solution I found is to use a class that wraps the two:

scala> case class StateWithVal[T](f: StateM[T], v: T) {def apply() = StateWithVal(f, f(v)._2)}
defined class StateWithVal

scala> val sv:StateWithVal[_] = StateWithVal(c, 0)
sv: StateWithVal[_] = StateWithVal(<function1>,0)

scala> sv()
res15: StateWithVal[_] = StateWithVal(<function1>,1)
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文