我有一个场景,我有一些对象需要互相参考.我可以编译的唯一方法是使用lazy
class A(b:B)
class B(a:A)
lazy val a:A = new A(b)
lazy val b:B = new B(a)
Run Code Online (Sandbox Code Playgroud)
我可以使用一些演员做同样的事情,并让它也编译
abstract class Message
case class Message1 extends Message
case class Message2 extends Message
class Actor1(otherActor:Actor) extends Actor {
def act() {
loop {
react {
case Message1 =>
println("received message1")
otherActor ! Message2
case _ =>
}
}
}
}
class Actor2(otherActor:Actor) extends Actor {
def act() {
loop {
react {
case Message2 =>
println("received message2")
otherActor ! Message1
case …Run Code Online (Sandbox Code Playgroud) 我不知道术语"懒惰"二进制搜索是否有效,但我正在阅读一些旧资料,我只是想知道是否有人可以解释懒惰二进制搜索的算法并将其与非惰性二进制文件进行比较搜索.
比方说,我们有这一系列的数字:
2, 11, 13, 21, 44, 50, 69, 88
Run Code Online (Sandbox Code Playgroud)
如何11使用Lazy Binary Search查找号码?
我使用的结构可以表示为:
IEnumerable<KeyValuePair<TKey, TValue>>
Run Code Online (Sandbox Code Playgroud)
鉴于它写的时间太长(不计算代码分析可能会发出警告),我宁愿使用更具表现力的类型..NET Framework中是否有这样的类型,或者我应该创建自己的类型?
请注意,它与字典不同:
IDictionary<TKey, TValue> : IEnumerable<KeyValuePair<TKey, TValue>>
Run Code Online (Sandbox Code Playgroud)
因为字典确保每个键都是唯一的,这不是我的情况.我也不能使用查找:
Lookup<TKey, TValue> : IEnumerable<IGrouping<TKey, TValue>>
Run Code Online (Sandbox Code Playgroud)
因为查找不是懒惰的,即它需要刷新所有数据才能对其进行分组.
在尝试使用列表理解来使列表成为条件列表时,我看到以下内容:
In [1]: mydicts = [{'foo':'val1'},{'foo':''}]
In [2]: mylist = [d for d in mydicts if d['foo']]
In [3]: mylist
Out[3]: [{'foo': 'val1'}]
In [4]: mydicts[1]['foo'] = 'val2'
In [5]: mydicts
Out[5]: [{'foo': 'val1'}, {'foo': 'val2'}]
In [6]: mylist
Out[6]: [{'foo': 'val1'}]
Run Code Online (Sandbox Code Playgroud)
我一直在阅读文档以尝试理解这一点,但到目前为止却一无所获,所以我在这里问我一个问题:为什么即使列表理解中的引用指向,它也mylist从不包含,为什么包含?这是因为Python急切地评估列表理解吗?还是懒惰/渴望的二分法完全与此无关?{'foo': 'val2'}mydictIn [6]{'foo': 'val2'}
此代码仅使用1Mb的RAM:
main = putStrLn $ show $ length (take 2000000 [1..])
Run Code Online (Sandbox Code Playgroud)
虽然此代码使用90Mb的RAM:
nums :: [Int]
nums = nextInts 0
where
nextInts x = x : nextInts (succ x)
main = putStrLn $ show $ length (take 2000000 nums)
Run Code Online (Sandbox Code Playgroud)
如果我这样改变它,它将再次使用1Mb的RAM:
nums :: [Int]
nums = nextInts 0
where
nextInts x
|x == 90000000 = [] -- some large number
|otherwise = x : nextInts (succ x)
main = putStrLn $ show $ length (take 2000000 nums)
Run Code Online (Sandbox Code Playgroud)
问题:有人可以解释为什么第二个代码示例将整个列表存储在RAM中,而第三个代码样本没有这样做.还描述了我应该如何更改第二个样本以使用O(1)RAM并且仍然是无限列表.
我已经注意到,我几乎完全使用lazy val分配,因为他们往往避免不必要的计算,我不能看到,许多情况下一个会不会想这样做(在可变的变量是当然的一个明显的例外依赖).
在我看来,这是函数式编程的一大优势,应尽可能鼓励它的使用,如果我理解正确,Haskell默认情况下就是这样做的.
那么为什么Scala值默认不是懒惰?是否仅仅是为了避免与可变变量相关的问题?
我正在浏览Haskell中的Functional Systems幻灯片.在该讲座中,定义了一个函数recDir2,用于unsafeInterleaveIO递归列出目录中的所有文件:
import qualified Data.ByteString.Lazy as L
recDir2 :: FilePath -> IO [FilePath]
recDir2 dir = do
ds <- openDirStream dir
let protect m = m `onException` closeDirStream ds
nextName = unsafeInterleaveIO $
protect (readDirStream ds) >>= checkName
checkName "" = closeDirStream ds >> return []
checkName "." = nextName
checkName ".." = nextName
checkName name = getSymbolicLinkStatus path >>= checkStat path
where path = dir </> name
checkStat path stat
| …Run Code Online (Sandbox Code Playgroud) 有没有办法评估无限列表之间的列表差异?例如,([1..] \\ [2*n | n <- [1..]])应该求[1,3,5,7,... ].不幸的是,它似乎迫使对第一个或第二个列表或两者进行评估.有没有办法避免这个得到答案?即使使用take 5 ([1..] \\ [2*n | n <- [1..]])不评估[1,3,5,7,9],这显然是正确的.注意,\\运算符是从Data.List导入的.
我玩严格的评估,向量和矩阵,得到了一个相当奇怪的结果.有以下代码:
module Test where
import qualified Data.Vector as V
import qualified Data.Matrix as M
import Control.DeepSeq
matrixCtor :: Int -> Int -> Int -> M.Matrix Int
matrixCtor x y size = M.matrix size size $ \(i,j) -> x*i+y*j
f :: M.Matrix Int -> M.Matrix Int
f b = c
where
n = M.nrows b
bt' = V.generate n $ \j -> M.getCol (j+1) b
c = M.matrix n n $ \(i,j) -> V.sum (V.unsafeIndex bt' (j-1))
Run Code Online (Sandbox Code Playgroud)
我将其加载到ghci并执行以下操作:
*Main Test> :set …Run Code Online (Sandbox Code Playgroud) --defining function
safeHead :: [a] -> Maybe a
safeHead [] = Nothing
safeHead (x:_) = Just x
--calling function
safeHead (4:5:3:[]:[])
Run Code Online (Sandbox Code Playgroud)
当我使用参数(4:5:3:[]:[])调用safeHead时,模式仅计算参数以查看它是否为空或是否有头.因此,尽管无意义的位"[]:[]"它不应该抛出错误,因为这部分甚至没有被评估.
lazy-evaluation ×10
haskell ×5
memory ×2
scala ×2
.net ×1
actor ×1
c# ×1
forward ×1
ghc ×1
ienumerable ×1
list ×1
performance ×1
python ×1
reference ×1