【发布时间】:2016-12-29 20:08:28
【问题描述】:
我正在学习 monad 转换器,但在对它们进行排序时遇到了问题
我创建了一个类型OptionTBitSetState[T]
我将这种类型理解为可能会失败的有状态计算
import scalaz._, Scalaz._
import scala.collection.immutable.BitSet
type BitSetState[T] = State[BitSet, T]
type OptionTBitSetState[T] = OptionT[BitSetState, T]
object OptionTBitSetState {
def apply[T](option : Option[T]) : OptionT[BitSetState, T] =
OptionT[BitSetState, T](State[BitSet, Option[T]](_ -> option))
def apply[T](state : State[BitSet, T]) : OptionT[BitSetState, T] =
OptionT[BitSetState, T](state.map(_.some))
}
我有一个带有签名的函数step
def step(i : Int) : OptionTBitSetState[Seq[Int]]
这个函数应该:
- 检查状态内的BitSet是否包含参数
i - 如果不包含:将
i添加到BitSet并返回Seq(i, i*10, i*100) - 如果它包含:失败并显示
None
- 如果不包含:将
函数步骤的实现:
def step(i : Int) : OptionTBitSetState[Seq[Int]] =
for {
usedIs <- OptionTBitSetState(get[BitSet])
res <- OptionTBitSetState(
Some(Seq(i, i*10, i*100)).filterNot(_ => usedIs.contains(i))
)
_ <- OptionTBitSetState(put(usedIs + i))
} yield res
我想对 步骤 列表进行排序,这样当我评估这个序列时,我会得到一个选项列表。但是sequence的签名不同。我得到了一个列表选项。
例如
List(1,2,1,3).map(step).sequence.run(BitSet.empty)
返回None,但我想要的是:
List(Some(Seq(1, 10, 100)), Some(Seq(2, 20, 200)), None, Some(Seq(3, 30, 300)))
有什么办法可以结合OptionTBitSetState[T]s,所以我会得到我需要的行为?
【问题讨论】:
标签: scala monads scalaz monad-transformers