加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

scala – 从可变算法中发现功能算法

发布时间:2020-12-16 18:10:23 所属栏目:安全 来源:网络整理
导读:这不一定是 Scala问题,它是一个设计问题,与避免可变状态,功能思维和那种排序有关.碰巧我正在使用Scala. 鉴于这一系列要求: 输入来自1到10之间的基本无限的随机数流 最终输出为SUCCEED或FAIL 在任何特定时间都可以有多个对象“收听”流,并且他们可以在不同的
这不一定是 Scala问题,它是一个设计问题,与避免可变状态,功能思维和那种排序有关.碰巧我正在使用Scala.

鉴于这一系列要求:

>输入来自1到10之间的基本无限的随机数流
>最终输出为SUCCEED或FAIL
>在任何特定时间都可以有多个对象“收听”流,并且他们可以在不同的时间开始收听,因此他们可能对“第一”数字有不同的概念;因此,流的监听器需要与流本身分离.

伪代码:

if (first number == 1) SUCCEED
else if (first number >= 9) FAIL
else {
  first = first number
  rest  = rest of stream
  for each (n in rest) {
    if (n == 1) FAIL
    else if (n == first) SUCCEED
    else continue
  }
}

这是一个可能的可变实现:

sealed trait Result
case object Fail extends Result
case object Succeed extends Result
case object NoResult extends Result

class StreamListener {
  private var target: Option[Int] = None

  def evaluate(n: Int): Result = target match {
    case None =>
      if (n == 1) Succeed
      else if (n >= 9) Fail
      else {
        target = Some(n)
        NoResult
      }

    case Some(t) =>
      if (n == t) Succeed
      else if (n == 1) Fail
      else NoResult
  }
}

这会起作用,但闻起来对我来说. StreamListener.evaluate不是引用透明的.并且使用NoResult令牌感觉不对.它虽然清晰易用/代码,但确实具有优势.除此之外,还有一个功能性解决方案吗?

我想出了其他两个可能的选择:

>评估返回一个(可能是新的)StreamListener,但这意味着我必须使Result成为StreamListener的子类型,感觉不对.
>让评估将Stream [Int]作为参数,让StreamListener负责消耗尽可能多的Stream,以确定失败或成功.我在这种方法中看到的问题是,注册侦听器的类应该在生成每个数字后查询每个侦听器,并在失败或成功时立即采取适当的操作.通过这种方法,我不知道如何发生这种情况,因为每个监听器都强制评估Stream,直到完成评估.这里没有单一数字生成的概念.

有没有标准的Scala / FP成语我在这里俯瞰?

解决方法

考虑到您的第一个可能的选项,我不确定为什么您将Result作为StreamListener的子类型,而不是只使用与StreamListeners相关的Result的特定子类型.

sealed trait Result
sealed trait FinalizedResult extends Result

trait StreamListener {
  def evaluate(n: Int): Result
}

case object Uninitialized extends Result with StreamListener {
  def evaluate(n: Int): Result = {
    n match {
      case i if (n == 1) => Succeed
      case i if (n >= 9) => Fail
      case _ => Initialized(n)
    }
  }
}

case class Initialized(target: Int) extends Result with StreamListener {
  def evaluate(n: Int): Result = {
    n match {
      case i if (n == target) => Succeed
      case i if (n == 1) => Fail
      case _ => this
    }
  } 
}

case object Succeed extends FinalizedResult
case object Fail extends FinalizedResult

但是,你是不是只是将可变性改为调用代码来跟踪对Results / StreamListeners的引用?

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读