Cha*_*dan 3 evaluation haskell list
我正在研究haskell书,我理解:sprint x用于打印x的元素已经被评估,而元素则没有(那些不是由'_'表示的).
书中提供的一个例子,
Prelude> let blah = enumFromTo 'a' 'z'
Prelude> :sprint blah
blah = _
Prelude> take 1 blah
"a"
Prelude> :sprint blah
blah = 'a' : _
Run Code Online (Sandbox Code Playgroud)
为了测试不同的输入,我在GHCi中做了这个: -
prelude> let b = [1,2,3,4,5]
prelude> :sprint b
b = _
prelude> take 1 b
[1]
prelude> :sprint b
b = _
Run Code Online (Sandbox Code Playgroud)
:sprint b最后一个命令的输出不应该是b = 1 : _因为我们在使用命令时只评估一个列表项和一个cons运算符take 1 b?? 但它显示了上面的输出.这是怎么发生的?输出不应该类似于String类型的输出吗?
编辑:我一直在尝试更多并得到这个结果: -
prelude> let b = [1..10] :: [Int]
prelude> :sprint b
b = _
prelude> take 3 b
[1,2,3]
prelude> :sprint b
b = 1 : 2 : 3 : _
Run Code Online (Sandbox Code Playgroud)
好吧,我最初的猜测是,这是因为我正在构建两个列表的方式?一个是使用范围而另一个是通过显式声明其元素(它依次通过在其元素上递归使用cons':'构造函数来创建列表)
行为:sprint可能有点棘手.在这种情况下,请查看以下类型x:
> :t x
x :: Num t => [t]
Run Code Online (Sandbox Code Playgroud)
因为它是多态的,所产生的实际值取决于Num您需要的特定实例.因此,当它可以确定您希望元素具有什么类型时,x行为更像是一个将生成列表的函数[1,2,3,4,5].
现在你可能会想,"好吧,我会创建一个非多态的列表",所以你试试这个:
> let x = [1,2,3,4,5 :: Int]
> :t x
x :: [Int]
> :sprint x
x = [1,2,3,4,5]
Run Code Online (Sandbox Code Playgroud)
有没有搞错?如果你考虑一下,这是有道理的.我们已经明确告诉ghci列表是什么.它不是可以取消评估它,然后再重新评估它.(无论如何这都是浪费.)但是让我们看看当我们尝试在x上映射函数时会发生什么:
> let y = map (+1) x
> :sprint y
y = _
> take 1 y
[2]
> :sprint y
y = 2 : _
Run Code Online (Sandbox Code Playgroud)
正如所料!
希望有所帮助.懒惰的评估是关于Haskell的一个棘手的问题(当它变得重要时).