vik*_*ata 15 debugging haskell lazy-evaluation ghci
Prelude> let a = 3
Prelude> :sprint a
a = _
Prelude> let c = "ab"
Prelude> :sprint c
c = _
Run Code Online (Sandbox Code Playgroud)
它为什么总是打印_
?我不太了解:sprint
命令的语义.
Mat*_*hid 14
Haskell是一种懒惰的语言.在"需要"之前,它不会评估结果.
现在,只需打印一个值就可以"满足"所有这些值.换句话说,如果在GHCi中键入表达式,它将尝试打印出结果,这会导致全部被评估.通常这就是你想要的.
该sprint
命令(这是一个GHCi功能,不是Haskell语言的一部分)允许您查看此时已评估了多少值.
例如:
Prelude> let xs = [1..]
Prelude> :sprint xs
xs = _
Run Code Online (Sandbox Code Playgroud)
所以,我们刚刚宣布xs
,它目前尚未评估.现在让我们打印出第一个元素:
Prelude> head xs
1
Prelude> :sprint xs
xs = 1 : _
Run Code Online (Sandbox Code Playgroud)
现在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 : _
Run Code Online (Sandbox Code Playgroud)
现在评估前10个元素,但仍有更多元素.(因为这xs
是一个无限的列表,这并不奇怪.)
您可以构建其他表达式并一次评估它们以查看正在发生的事情.这实际上是GHCi调试器的一部分,它允许您一次一步地执行代码.特别是如果你的代码被无限循环捕获,你不想做print
任何事情,因为这可能会锁定GHCi.但是你仍然希望看到发生了什么...因此sprint
,它可以让你看到到目前为止评估了什么.
哈斯克尔很懒.它不会在需要之前对事物进行评估.
GHCi sprint
命令(不是Haskell的一部分,只是解释器的调试命令)打印表达式的值而不强制求值.
当你写作
let a = 3
Run Code Online (Sandbox Code Playgroud)
你将一个新名称绑定a
到右侧表达式,但Haskell还不会评估那个东西.因此,当您使用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
Run Code Online (Sandbox Code Playgroud)
我有点晚了,但我遇到了类似的问题:
?: let xs = [1,2,3]
xs :: Num t => [t]
?: :sprint xs
xs = _
?: print xs
?: :sprint xs
xs = _
Run Code Online (Sandbox Code Playgroud)
此问题特定于多态值.如果你已经-XNoMonomorphismRestriction
启用ghci永远不会真正评估/强制xs
,它只会评估/强制专业化:
?: :set -XMonomorphismRestriction
?: let xs = [1,2,3]
xs :: [Integer]
?: print xs
?: :sprint xs
xs = [1,2,3]
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
1187 次 |
最近记录: |