Why it does not show as evaluated? [duplicate]

落爺英雄遲暮 提交于 2020-01-04 04:22:12

问题


I am trying to figure out, how lazy evaluation works and I've tried as following:

Prelude> a = [1,2,3,5,6]
Prelude> b = map (\x -> x * 8) a
Prelude> :sprint b
b = _
Prelude> b
[8,16,24,40,48]
Prelude> :sprint b
b = _ 

The question is, why the last line does not show the evaluated list? I evaluated a line before.


回答1:


Because b is basically a function from Num a dictionary to [a] for some a. If this were a concrete type then it would be as you expected:

let a Prelude> let a = [1..4] :: [Int]
Prelude> let b = map (*8) a
Prelude> :sprint b
b = _
Prelude> b
[8,16,24,32]
Prelude> :sprint b
b = [8,16,24,32]

EDIT

Side by side it will hopefully be even more apparent:

Prelude> let a = [1..4]
Prelude> :t a
a :: (Num a, Enum a) => [a]
Prelude> let poly_b = map (*8) a
Prelude> let concrete_b = map (* (8 ::Int)) a
Prelude> :sprint poly_b
poly_b = _
Prelude> :sprint concrete_b
concrete_b = _
Prelude> poly_b
[8,16,24,32]
Prelude> concrete_b
[8,16,24,32]
Prelude> :sprint poly_b
poly_b = _
Prelude> :sprint concrete_b
concrete_b = [8,16,24,32]

EDIT 2: It occurs to me that the monomorphism restriction, or lack thereof in the REPL, could be causing some confusion. In compiled code the value in a let statement would take on a single concrete type and not be polymorphic, thus not have this "problem" at all:

Prelude> :set -XMonomorphismRestriction
Prelude> let a = [1..4]
Prelude> let b = map (*8) a
Prelude> :sprint b
b = _
Prelude> b
[8,16,24,32]
Prelude> :sprint b
b = [8,16,24,32]


来源:https://stackoverflow.com/questions/54675020/why-it-does-not-show-as-evaluated

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!