Lazy computation 在實際應用中有什麼妙用?

時間 2021-05-30 11:59:56

1樓:dram

黑科技,可持久化平攤 O(1) push/pop 的雙端佇列

可持久化。。平攤?

如果平攤的話,我對 X 進行操作 foo 是乙個比較慢的操作,那麼我不停地對 X 進行操作 foo 豈不是破壞了平攤的性質了?

Okasaki:No.

完全可以讓你對 X 兩次操作得到的結果中,有部分是共享的 thunk,這樣只要在一邊對這個 thunk 求值,另一邊的 thunk 也就變成乙個值了。

這個資料結構俗稱 Data.Sequence,文件在此: http://

hackage.haskell.org/pac

kage/containers-0.5.8.1/docs/Data-Sequence.html

。還支援 split index 等操作哦

其中用到的技巧在 Chris Okasaki 的 Purely Functional Data Structures 有描述

這裡有個簡化的版本,它只是乙個單向的佇列,也是用到類似的技巧:http://www.

可惜我完全理解不了這個資料結構黑科技。說點我懂的吧。

乙個比給二叉樹標號實際點的工作:一次遍歷完成彙編操作。

彙編裡可能會出現這種狀況:

something

jmpLabel

movblah

,blah

; \

movblah

,blah

; \

; \

Label:

;

我們要提前知道 Label 所指向的位置,但是我們還沒看到過 Label 呢。怎麼辦呢?

我們把所有標籤指向的位置存成乙個 Map。彙編的過程中,jmp 指令從 Map 中讀取標籤對應的位置,遇到標記就把標記和對應位置存在 Map 裡。

assemblerHelper

::Map

String

Int->

String

-- The input

->([Instruction

],Map

String

Int)

然後高能的部分來了。不是要那個 Map 嘛,我們把它傳回去就行了assembler

::String

->[Instruction

]assembler

input

=let

(inss

,table)=

assemblerHelper

table

input

ininss

只要乙個標籤的位置本身不會影響到 jmp 指令的生成(比如標籤是指令的編號而不是位元組數),這樣就做完了

因為我們其實走到 jmp 那裡的時候,在生成的 Instruction 裡面留下了乙個坑,等遍歷完的時候再去看那個 Instruction 的時候,其實坑早就填上了——就在 Map 裡面呢

2樓:「已登出」

比如說,要是有 lazy computation的話

這個就很好解決了 說個logging的效能問題, 一般我們寫log 用... 來自韋恩卑鄙

@王韋恩卑鄙

3樓:

乙個用處就是可以用來定義操作符

操作符跟函式還是有區別的,操作符不只是函式的語法糖。操作符是可以短路的,而函式一般不會。操作符其實更像是for,while,if,goto這樣的語法控制結構,而不是更像是函式。

一門語言缺少一些內建函式並不會限制它的表達能力,但是缺少一些特定的操作符,就會限制其表達能力了。

當能夠用函式呼叫的語法實現短路操作時,你就獲得了 「自定義語法結構」 的力量。要麼就是用巨集,要麼就要惰性求值(lazy evaluation),這兩個,乙個是lisp,乙個是haskell

如果理解程式語言中「操作符」(operator)的概念? - C++

4樓:夏梓耀

其實Scala的lazy關鍵字是很常用的(非常常見),比如:在有些資源沒有必要一開始就載入的情況下就會宣告為lazy的,在用到時再去初始化;比如:同乙份code可能需要按role初始化不同型別例項的時候也會宣告為lazy (如Akka Cluster 按role需要啟動不同的Actor時),在某種程度上Scala的lazy是來Fix val關鍵字(因為是final)的立即求值特點的。

不過Lazy computation 在Scala裡不止是lazy關鍵字, 更重要的是call-by-name (記得翻譯為:傳名函式)

defpair(x

:=>

Int):(

Int,

Int)=(

x,x)

(注:class構造函式引數不可以是non-strict, 所以要lazy必須傳函式() => ???)

那麼就來說說傳名函式的實際應用吧!

常見的一種情況就是Infinite Stream無窮資料流(或叫Generator)了,而很多東西都可以視為無窮資料流,比如資料庫查詢分頁操作,為其定義乙個getMore操作(比如前端瀑布流):

defgetData(s

:Int,l

:Int)=

Option

(s"sql...skip=

$slimit=$l"

)def

getMore

(skip

:Int

,limit

:Int)=

Stream

.unfold

(skip

)println

(Stream

.getMore(0

,10).take(3

).toList

)//>>>

List

(Some

(sql

...skip=0

limit=10

),Some

(sql

...skip=10

limit=10

),Some

(sql

...skip=20

limit=10))

Clojure語言在實際應用中有什麼成功的案列沒?

最近很火的雙向鏈結筆記軟體 Roam Research 就是基於 Clojure ClojureScript 開發的。Roam 合夥人在 HackerNews 上的回覆 狗好看 Continuous Integration and Delivery Circle CI,這個也算比較出名的吧,這個是C...

AngularJS 在實際應用中有哪些優缺點?

James Bjorn 說說我遇到的缺點吧 two way binding雖然很方便,但是一不小心就會弄出過多watcher,導致慢。ng repeat在IE上面特別慢 Google已經把angularjs交還給了community了,更新和bug fix估計都不會很穩定 總體來說,主要就是慢。學習...

線性代數對角化在實際生活中有什麼應用?

你每天用的搜尋引擎,推薦系統中,或檔案壓縮應用中,有可能就涉及到解矩陣對角化問題。對角化,一般是指SVD分解,如果矩陣剛好是對稱的,也可以叫相似對角化。對角化其實是很難的,因為一旦能對角化,就可以求出矩陣的特徵值,這是乙個無法在有限時間內完成的任務。對於對稱陣,Jacobi迭代法和power met...