gpt4 book ai didi

scala - 什么是 "functional way"以避免将状态选择上下文向下传递到调用堆栈?

转载 作者:行者123 更新时间:2023-12-04 02:00:17 25 4
gpt4 key购买 nike

假设我有一个有两个列表的特征。有时我对一个感兴趣,有时对另一个感兴趣。

trait ListHolder {
val listOne = List("foo", "bar")
val listTwo = List("bat", "baz")
}

我有一个函数调用链,在它的顶部我有我需要在列表之间选择的上下文,但在它的底部我使用特征。

在命令式范式中,我通过函数传递上下文:
class Imperative extends Object with ListHolder {
def activeList(choice : Int) : List[String] = {
choice match {
case 1 => listOne
case 2 => listTwo
}
}
}

def iTop(is : List[Imperative], choice : Int) = {
is.map{iMiddle(_, choice)}
}

def iMiddle(i : Imperative, choice : Int) = {
iBottom(i, choice)
}

def iBottom(i : Imperative, choice : Int) = {
i.activeList(choice)
}

val ps = List(new Imperative, new Imperative)
println(iTop(ps, 1)) //Prints "foo, bar" "foo,bar"
println(iTop(ps, 2)) //Prints "bat, baz" "bat, baz"

在面向对象范式中,我可以使用内部状态来避免向下传递上下文:
class ObjectOriented extends Imperative {
var variable = listOne
}

def oTop(ps : List[ObjectOriented], choice : Int) = {
ps.map{ p => p.variable = p.activeList(choice) }
oMiddle(ps)
}

def oMiddle(ps : List[ObjectOriented]) = oBottom(ps)

def oBottom(ps : List[ObjectOriented]) = {
ps.map(_.variable) //No explicitly-passed-down choice, but hidden state
}

val oops = List(new ObjectOriented, new ObjectOriented)

println(oTop(oops, 1))
println(oTop(oops, 2))

在函数式语言中实现类似结果的惯用方法是什么?

也就是说,我希望下面的输出类似于上面的输出。
class Functional extends Object with ListHolder{
//IDIOMATIC FUNCTIONAL CODE
}

def fTop(fs : List[Functional], choice : Int) = {
//CODE NEEDED HERE TO CHOOSE LIST
fMiddle(fs)
}

def fMiddle(fs : List[Functional]) = {
//NO CHANGES ALLOWED
fBottom(fs)
}

def fBottom(fs : List[Functional]) = {
fs.map(_.activeList) //or similarly simple
}

def fs = List(new Functional, new Functional)

println(fTop(fs, 1))
println(fTop(fs, 2))

更新:
这会被认为是正常工作吗?
class Functional extends Imperative with ListHolder{}

class FunctionalWithList(val activeList : List[String]) extends Functional{}

def fTop(fs : List[Functional], band : Int) = {
fMiddle(fs.map(f => new FunctionalWithList(f.activeList(band))))
}

def fMiddle(fs : List[FunctionalWithList]) = {
//NO CHANGES ALLOWED
fBottom(fs)
}

def fBottom(fs : List[FunctionalWithList]) = {
fs.map(_.activeList)
}

def fs = List(new Functional, new Functional)

println(fTop(fs, 1))
println(fTop(fs, 2))

最佳答案

好吧,人们总是可以使用 monads 和 monadic comprehensions 来处理这种事情,但问题的核心是,不是将选择向下传递到堆栈,而是将函数返回到堆栈上,直到有人知道如何解决问题可以处理。

def fTop(fs : List[Functional]) = {
fMiddle(fs)
}

def fMiddle(fs : List[Functional]) = {
fBottom(fs)
}

def fBottom(fs : List[Functional]) = {
(choice: Int) => fs map (_ activeList choice)
}

进而
println(fTop(fs)(1))

一旦你开始为这种事情开发模式,你最终会得到各种各样的 monad(每种 monad 代表一个特定的模式)。

关于scala - 什么是 "functional way"以避免将状态选择上下文向下传递到调用堆栈?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9730983/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com