【问题标题】:type safe state handling in functions函数中的类型安全状态处理
【发布时间】:2011-02-03 05:13:47
【问题描述】:

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

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

这是一个 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)
              ^

【问题讨论】:

  • 我很困惑为什么你会期望 a(z) 工作,这相当于 c(0: Any),这显然是无效的 - 你不能将 Any 传递给一个接受Int。你能解释一下你希望在这里发生什么吗?
  • 我希望我可以在一张地图中保留使用不同状态的函数。函数中的 T 是状态的类型。

标签: scala functional-programming state


【解决方案1】:

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

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)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-01-27
    • 1970-01-01
    • 2019-07-17
    • 2011-12-03
    • 2012-10-31
    • 2019-05-26
    相关资源
    最近更新 更多