Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/269.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# te(i) i+=1 } } } 重置{ loopWhile(真){ println(“生成:+g.next”) } } } }_C#_Scala_Yield - Fatal编程技术网

C# te(i) i+=1 } } } 重置{ loopWhile(真){ println(“生成:+g.next”) } } } }

C# te(i) i+=1 } } } 重置{ loopWhile(真){ println(“生成:+g.next”) } } } },c#,scala,yield,C#,Scala,Yield,如前所述,您可以使用continuations插件创建一个生成器来创建一个与C#完全相同的收益率: 导入scala.util.continuations_ 最温柔的对象{ val gen=新生成器[Int]{def product={ 产量价值(1) 产量价值(2) 产量价值(3) 线程。睡眠(1000) 产量价值(42) }} def main(参数:数组[字符串]):单位={ 对于(v单位)=空 def PRODUCT():单位@cps[单位] def foreach(f:=>(E=>单位)

如前所述,您可以使用continuations插件创建一个生成器来创建一个与C#完全相同的收益率:

导入scala.util.continuations_
最温柔的对象{
val gen=新生成器[Int]{def product={
产量价值(1)
产量价值(2)
产量价值(3)
线程。睡眠(1000)
产量价值(42)
}}
def main(参数:数组[字符串]):单位={
对于(v单位)=空
def PRODUCT():单位@cps[单位]
def foreach(f:=>(E=>单位)):单位={
loopFn=f
重置[单位,单位](生产)
}
def yieldValue(值:E):单位@cps[单位]=
移位{genK:(单位=>Unit)=>
loopFn(值)
耿(())
()
}
}

来自C#背景并调试了hotzen的Scala代码(适用于Scala 2.11.6),我必须说这个continuations的用法接近于C#yield的等价用法。我不知道如果需要多个生成器,以相同的方法运行,或者可能分布在不同的方法中,continuations是否仍然会起到类似的作用,但我很高兴continuations确实存在,这样我就不会被迫使用多个线程来实现ac请记住类似的,或者传递回电。

谢谢James,我会检查一下。不,它们不一样。Scala 2.7.x没有与C#的“yield”等效的构造。不过,在Scala 2.8.x中,由于使用了带分隔符的Continuation编译器插件,可以使用Continuation来模拟C#的“yield”来编写构造很容易。我有没有想过如何调和詹姆斯和沃尔特显然矛盾的答案?詹姆斯,我试过斯卡拉的理解,到目前为止,我觉得它们总是以“for enums yield item”的形式出现在C#中,这是一种不同的机制,允许您在方法中的任意点多次调用yield,允许您为任何数据创建迭代器,而Scala中的理解似乎是编写序列的一种很好的方式。@Alex Black-希望今晚我有时间仔细查看并比较它们更好。谢谢亚历克斯,这是一个很好的例子。问题1:鲍尔斯(2,8)是怎么做的工作?问题2:在C#中,使用yield,我可以很容易地为任何数据结构编写一个迭代器,只需对每个项进行“yield”即可。例如,我可以很容易地通过DAG生成一个深度优先的迭代器。在Scala中我该如何做到这一点?Alex,再读一遍,我认为您的示例有点偏离基础。1.它不懒惰(我不认为)就像微软的C#示例is.2一样,你也可以用C#来实现它:(e)=>Enumerable.Range(e,e+1)。选择(n=>f(Math.Power(e,n)))a)Powers(2,8)是如何工作的?我不确定你在问什么。map调用循环遍历范围的每个元素(本质上是List(1,2,3,4,5,6,7,8))并调用与f(数字,指数)一起传递的方法其中,指数是范围的当前元素。b)当然,我认为你可以让它做C#的产量可以做的任何事情,而且更多C)它是懒惰的,如果你是说它在计算每个结果时调用println的话。d)当然你可以在C#中这样做,但它没有演示自定义迭代。当我问Powers(2,8)是怎么做的如果成功了,我的意思是,是什么使你能够写出幂(2,8)而不是幂。应用(2,8)。我用我的一个对象尝试了这一点,但没有效果。尽管C#迭代器可以是有状态的,但它们不一定是有状态的。它们允许以过程式的方式编写。函数式语言没有理由不支持语法糖来模拟过程式。即使是“爸爸”Haskell通过其对monad上的核心操作集的语法支持这一点,允许(例如)以类似于过程编码的方式编写IO操作(当IO副作用的顺序必然至关重要时,这一点很重要).换句话说,即使是最纯粹的语言也必须找到一种可以接受的方式来变得不纯净。我认为你已经一针见血了。听起来Java正在获得本地协同程序,这可能也会使Scala能够实现:当然,C#的收益率更直观。而且你也不能以这种方式链接调用,如:graph.BreadthFirstTraversal()。其中(…)。是的,它使用带有“scalac-P:continuations:enable”的新CPS编译器插件。我不知道插件是否会默认集成。生成器的一流支持会很好,也许有一天。使用Scala 2.9.1我收到一个错误:
java.lang.NoSuchMethodError:Scala.util.continuations.package$.shift(Lscala/Function1;)Ljava/lang/Object
。知道我做错了什么吗?这个问题在另外两个地方也得到了回答:对于如何使它与
for
语句兼容的问题,也有一个答案:
public class Graph<T> {
   public IEnumerable<T> BreadthFirstIterator() {
      List<T> currentLevel = new List<T>();
      currentLevel.add(_root);

      while ( currentLevel.count > 0 ) {
         List<T> nextLevel = new List<T>();
         foreach( var node in currentLevel ) {
            yield return node;
            nextLevel.addRange( node.Children );
         }
         currentLevel = nextLevel;
      }
   }
}
graph.BreadthFirstIterator().foreach( n => Console.WriteLine( n ) );
object Powers {
  def apply(number:Int, exponent:Int) (f:(Double) => Any) = {
    (new Range(1,exponent+1,1)).map{exponent => f(Math.pow(number, exponent))}
  }
}
scala> Powers(2,8){ println(_) }
2.0
4.0
8.0
16.0
32.0
64.0
128.0
256.0
def traverse(node:Node, maxDepth:Int)(f(Node) => Any)) { ... }
traverse(node, maxDepth) { (yieldValue) =>
  // this is f(yieldValue) and will be called for each value that you call f with
  println(yieldValue)
}
public class Graph<T> {
   public void BreadthFirstTraversal( Action<T> f) {
      List<T> currentLevel = new List<T>();
      currentLevel.add(_root);

      while ( currentLevel.count > 0 ) {
         List<T> nextLevel = new List<T>();
         foreach( var node in currentLevel ) {
            f(node);
            nextLevel.addRange( node.Children );
         }
         currentLevel = nextLevel;
      }
   }
}
graph.BreadthFirstTraversal( n => Console.WriteLine( n ) );
graph.BreadthFirstTraversal( n =>
{
   Console.WriteLine(n);
   DoSomeOtherStuff(n);
});
import scala.continuations._
import scala.continuations.ControlContext._

object Test {

  def loopWhile(cond: =>Boolean)(body: =>(Unit @suspendable)): Unit @suspendable = {
    if (cond) {
      body
      loopWhile(cond)(body)
    } else ()
  }

  abstract class Generator[T] {
    var producerCont : (Unit => Unit) = null
    var consumerCont : (T => Unit) = null

    protected def body : Unit @suspendable

    reset {
      body
    }

    def generate(t : T) : Unit @suspendable =
      shift {
        (k : Unit => Unit) => {
          producerCont = k
          if (consumerCont != null)
            consumerCont(t)
        }
      }

    def next : T @suspendable =
      shift {
        (k : T => Unit) => {
          consumerCont = k
          if (producerCont != null)
            producerCont()
        }
      }
  }

  def main(args: Array[String]) {
    val g = new Generator[Int] {
      def body = {
        var i = 0
        loopWhile(i < 10) {
          generate(i)
          i += 1
        }
      }
    }

    reset {
      loopWhile(true) {
        println("Generated: "+g.next)
      }
    }
  }
}
import scala.util.continuations._

object GenTest {

    val gen = new Generator[Int] { def produce = {
        yieldValue(1)
        yieldValue(2)
        yieldValue(3)
        Thread.sleep(1000)
        yieldValue(42)
  }}


    def main(args: Array[String]): Unit = {
        for (v <- gen) {
            println(v)
        }
    }
}

abstract class Generator[E] {

    var loopFn: (E => Unit) = null

    def produce(): Unit @cps[Unit]

  def foreach(f: => (E => Unit)): Unit = {
        loopFn = f
        reset[Unit,Unit]( produce )
  }

  def yieldValue(value: E): Unit @cps[Unit] =
    shift { genK: (Unit => Unit) =>
      loopFn( value )
      genK( () )
      ()
    }

}