内部函数编译器似乎不允许自递归val.请在此处查看以下示例
object Test {
val nats1 : Stream[Int] = 1 #:: (nats1 map (_ + 1)) // OK
def testfun() : Int = {
def nats2 : Stream[Int] = 1 #:: (nats2 map (_ + 1)) // OK
val nats3 : Stream[Int] = 1 #:: (nats3 map (_ + 1)) // Error!
nats2.head
}
def main(args : Array[String]) {
println(testfun)
}
}
Run Code Online (Sandbox Code Playgroud)
第一个定义工作并不是很令人惊讶,但第三个定义呢?为什么不允许在Scala中使用自我复兴的val内部函数?
这是一个遗憾,因为有时你想保持一个本地定义,但你希望它是一个值,而不是每次都完全评估的def.
一般来说,似乎没有必要进行限制.例如,以下Haskell-Code工作原理:
module Test where
nats1 :: [Int]
nats1 = 1 : (map (+1) nats1)
testfun :: …Run Code Online (Sandbox Code Playgroud) Jones和Launchbury在他们的论文 "Lazy Functional State Threads"中描述了ST monad.为了确保可变参数不能在它们创建的上下文(或"线程")之外使用,它们使用特殊类型,包括更高级别的类型.这有四个重要的例子:
newVar :: ? s a. a -> ST s (MutVar s a)
readVar :: ? s a. MutVar s a -> ST s a
writeVar :: ? s a. MutVar s a -> a -> ST s ()
runST :: ? a. (? s. ST s a) -> a
Run Code Online (Sandbox Code Playgroud)
为了理解这种结构背后的想法,我阅读了论文的前两部分.以下解释似乎是核心:
现在,我们真正想说的是,
newST应该只应用于一个状态转换器,它newVar用于创建在该线程中使用的任何引用.换句话说,runST不应该对初始状态下已分配的内容做出任何假设.也就是说,runST不管它给出的初始状态如何都应该工作.所以类型runST应该是:runST :: ? a. (? s. ST s a) -> a
解释很好,但我想知道它如何映射到所需类型的最终定义.我的问题是我不知道如何解释类型变量 …
我想学习使用ST-Monad.因此,我想为每个整数重写一些代码计算 - 达到极限 - 所有正确除数的列表.结果应该是一个数组,索引'n'的条目应该是它的适当除数的列表.
它是通过计算每个整数'n'的列表'l'的倍数,并在索引'm'的'l'中为每个'm'加上它的除数'n'到列表来完成的.
这是我想要修改的代码:
properDivisorsOf' :: forall a. (Integral a, Ix a) => a -> Array a [a]
properDivisorsOf' limit =
let generate :: (Integral a, Ix a) => a -> Array a [a] -> Array a [a]
generate n acc
| n > (limit `div` 2) = acc
| otherwise =
let acc' = acc // [(i, n : (acc ! i)) | i <- [2*n, 3*n .. limit]]
in generate (n + 1) acc'
in …Run Code Online (Sandbox Code Playgroud) Rust的书称ref关键词为“传统”。当我想遵循隐式建议避免时ref,如何在以下玩具示例中做到这一点?您也可以在操场上找到代码。
struct OwnBox(i32);
impl OwnBox {
fn ref_mut(&mut self) -> &mut i32 {
match *self {
OwnBox(ref mut i) => i,
}
// This doesn't work. -- Even not, if the signature of the signature of the function is
// adapted to take an explcit lifetime 'a and use it here like `&'a mut i`.
// match *self {
// OwnBox(mut i) => &mut i,
// }
// This doesn't work
// …Run Code Online (Sandbox Code Playgroud)