Debugging 原因:sprint总是打印一个_&引用;?

Debugging 原因:sprint总是打印一个_&引用;?,debugging,haskell,lazy-evaluation,ghci,Debugging,Haskell,Lazy Evaluation,Ghci,为什么它总是打印?我不太明白:sprint命令的语义。哈斯克尔很懒。在需要之前,它不会对事物进行评估 GHCisprint命令(不是Haskell的一部分,只是解释器的一个调试命令)在不强制求值的情况下打印表达式的值 当你写作时 Prelude> let a = 3 Prelude> :sprint a a = _ Prelude> let c = "ab" Prelude> :sprint c c = _ 您将一个新名称a绑定到右侧表达式,但Haskell还不会计算该

为什么它总是打印
?我不太明白
:sprint
命令的语义。

哈斯克尔很懒。在需要之前,它不会对事物进行评估

GHCi
sprint
命令(不是Haskell的一部分,只是解释器的一个调试命令)在不强制求值的情况下打印表达式的值

当你写作时

Prelude> let a = 3
Prelude> :sprint a
a = _
Prelude> let c = "ab"
Prelude> :sprint c
c = _
您将一个新名称
a
绑定到右侧表达式,但Haskell还不会计算该名称。因此,当您对它进行
sprint
时,它会打印
\uu
作为值,以指示表达式尚未计算

试试这个:

let a = 3

哈斯克尔是一种懒惰的语言。在“需要”之前,它不会评估结果

现在,只需打印一个值就可以“需要”所有值。换句话说,如果您在GHCi中键入表达式,它将尝试打印结果,这将导致对所有表达式进行求值。通常这就是你想要的

sprint
命令(这是一个GHCi功能,不是Haskell语言的一部分)允许您查看此时已计算了多少值

例如:

let a = 3
:sprint a -- a has not been evaluated yet
print a -- forces evaluation of a
:sprint a -- now a has been evaluated
所以,我们刚刚声明了
xs
,它目前未被评估。现在,让我们打印出第一个元素:

Prelude> let xs = [1..]
Prelude> :sprint xs
xs = _
现在GHCi已经评估了榜首,但仅此而已

Prelude> head xs
1
Prelude> :sprint xs
xs = 1 : _
现在对前10个元素进行了评估,但仍有更多元素保留。(因为
xs
是一个无限列表,这并不奇怪。)


您可以构造其他表达式,并一次对它们求值一点,以查看发生了什么。这实际上是GHCi调试器的一部分,它允许您一次一点地逐步完成代码。特别是如果您的代码陷入无限循环,您不想打印任何内容,因为这可能会锁定GHCi。但你还是想看看发生了什么。。。因此,
sprint
,它可以让您查看到目前为止的评估结果。

我有点晚了,但我遇到了类似的问题:

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 : _
此问题特定于多态值。如果启用了
-XNoMonomorphismRestriction
,ghci将永远不会真正计算/force
xs
,它将只计算/force专门化:

λ: let xs = [1,2,3]
xs :: Num t => [t]
λ: :sprint xs
xs = _
λ: print xs
λ: :sprint xs
xs = _

在:
:sprint c
之后尝试
seq c()
:它将给你
c='a':
。。。另外,请阅读我在上一个问题中发布的链接,让a=3更复杂(你应该试试这个)-默认情况下,
a
将是
a::Num a=>a
,并且在您的情况下将始终是
:sprint
-在我看来,
字符串
示例更适合于了解这一点如果您使用
let a=3
,您最好指定一个类型
let a=3::Int
,这样您就不会感到困惑,另请注意,在GHC 7.8中,在较旧版本中,此行为已发生变化。您不必在此语句中编写类型,即可使
:sprint
按“预期”工作。备注:由于
[1..]
具有多态类型,因此
:sp xs
很可能产生
.
,即使在
头xs
之后
let xs=[1..]:[Integer]
将解决此问题。请注意,这仅适用于“重载”值,如
xs
;具有变量类型且对这些变量具有类型类约束的对象。大多数情况下,只有涉及文字数字的例子才会有这种表现;不幸的是,数字显然是学习时要玩弄的东西。如果您改为使用布尔值(
True
False
&
,等等),那么无论
NoMonomorphismRestriction
或是否给出显式类型签名,所有内容的行为基本相同。
λ: :set -XMonomorphismRestriction
λ: let xs = [1,2,3]
xs :: [Integer]
λ: print xs
λ: :sprint xs
xs = [1,2,3]