Prelude> let a = 3
Prelude> :sprint a
a = _
Prelude> let c = "ab"
Prelude> :sprint c
c = _
爲什麼總是打印_
?我不完全明白:sprint
命令的語義。爲什麼:衝刺總是打印一個「_」?
Prelude> let a = 3
Prelude> :sprint a
a = _
Prelude> let c = "ab"
Prelude> :sprint c
c = _
爲什麼總是打印_
?我不完全明白:sprint
命令的語義。爲什麼:衝刺總是打印一個「_」?
Haskell是惰性語言。在「需要」之前它不會評估結果。
現在,只需要打印一個值導致所有的「需要」。換句話說,如果您在GHCi中輸入一個表達式,它會嘗試打印出結果,從而導致所有結果都被評估。通常這就是你想要的。
sprint
命令(這是GHCi功能,不屬於Haskell語言的一部分)允許您查看此時已評估了多少值。
例如:
Prelude> let xs = [1..]
Prelude> :sprint xs
xs = _
所以,我們只是宣佈xs
,並且它目前未評估。現在,讓我們打印出的第一個元素:
Prelude> head xs
1
Prelude> :sprint xs
xs = 1 : _
現在GHCI評估了列表的頭部,但僅此而已。
Prelude> take 10 xs
[1,2,3,4,5,6,7,8,9,10]
Prelude> :sprint xs
xs = 1 : 2 : 3 : 4 : 5 : 6 : 7 : 8 : 9 : 10 : _
現在評估前10個元素,但剩下更多。 (由於xs
是無限列表,這並不奇怪。)
您可以構造其他表達式並每次對它們進行一次評估以查看發生了什麼。這實際上是GHCi調試器的一部分,它可以讓您一次一步地完成代碼。特別是如果你的代碼陷入了無限循環,你不想print
什麼,因爲這可能會鎖定GHCi。但你仍然想看看發生了什麼......因此sprint
,它可以讓你看到迄今評估的東西。
備註:由於'[1 ..]'具有多態類型,因此':sp xs'可能產生'_',即使在'head xs'之後。 'let xs = [1 ..] :: [Integer]'會解決這個問題。 – Zeta
哈斯克爾很懶。在需要之前它不評估事物。
GHCi sprint
命令(不是Haskell的一部分,只是解釋器的調試命令)會打印表達式的值而不強制執行評估。
當你寫
let a = 3
綁定一個新的名字a
到右邊的表情,但哈斯克爾不會評價說事兒呢。因此,當您sprint
它時,它會打印_
作爲表示尚未評估表達式的值。
試試這個:
let a = 3
:sprint a -- a has not been evaluated yet
print a -- forces evaluation of a
:sprint a -- now a has been evaluated
中爲'let a = 3'發佈的鏈接,它比較複雜(你應該試試) - 默認情況下'a'將是'a :: Num a => a'並且在你的情況下將總是將':sprint'轉換爲'_' - IMO'String'示例更適合於如果你使用'let a = 3'來獲得這種感覺 – Carsten
,你最好指定一個類型'let a = 3 :: Int',所以你不會感到困惑,注意這個行爲在舊版本的GHC 7.8中已經改變了,你不必在這個語句中編寫類型來使':sprint'工作如'預期'。 – epsilonhalbe
我有點晚了,但我有一個類似的問題:
λ: let xs = [1,2,3]
xs :: Num t => [t]
λ: :sprint xs
xs = _
λ: print xs
λ: :sprint xs
xs = _
這個問題是針對多態值。如果你有-XNoMonomorphismRestriction
啓用ghci中永遠不會真正評估/力xs
,它只會評價/力特:
λ: :set -XMonomorphismRestriction
λ: let xs = [1,2,3]
xs :: [Integer]
λ: print xs
λ: :sprint xs
xs = [1,2,3]
請注意,這僅適用於「重載」值,如「xs」;那些具有變量類型並對這些變量具有類型類約束的東西。大多數情況下只有涉及字面數字的例子纔是這種行爲。不幸的是,數字是在學習時玩弄明顯的事情。如果你改用booleans('True','False','&&','和'等),那麼無論是否使用'NoMonomorphismRestriction',或者是否給出明確的類型簽名,所有內容大部分都是相同的。 – Ben
嘗試'序列C()'後:':衝刺C'會給你'C = 'a':_' ...還閱讀了我在你發佈的最後一個問題 – Carsten