Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/haskell/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Haskell 懒散,是文字读取(内部交互)所有输入,还是只读取所需内容?_Haskell - Fatal编程技术网

Haskell 懒散,是文字读取(内部交互)所有输入,还是只读取所需内容?

Haskell 懒散,是文字读取(内部交互)所有输入,还是只读取所需内容?,haskell,Haskell,我开始学习哈斯克尔,我正在努力理解 这些功能做了多少工作(特别是关于 懒惰的概念)。请看以下节目: main::IO() main = interact ( head . words) 该程序是读取所有输入还是仅读取输入中的第一个字?仅读取第一个字: % yes | ghc -e 'interact (head . words)' y % 但要注意:这依赖于一个称为“lazyio”的特性,该特性只与纯代码中的惰性技术有关。纯函数在默认情况下是懒惰的,您必须努力使其严格;IO在默认情况下是“严

我开始学习哈斯克尔,我正在努力理解 这些功能做了多少工作(特别是关于 懒惰的概念)。请看以下节目:

main::IO()
main = interact ( head . words)
该程序是读取所有输入还是仅读取输入中的第一个字?

仅读取第一个字:

% yes | ghc -e 'interact (head . words)'
y
%
但要注意:这依赖于一个称为“lazyio”的特性,该特性只与纯代码中的惰性技术有关。纯函数在默认情况下是懒惰的,您必须努力使其严格;IO在默认情况下是“严格IO”,您必须努力使其成为懒惰IO。一些库函数(特别是
interact
(h)getContents
,以及
readFile
)已经用于这项工作

第一个字:

% yes | ghc -e 'interact (head . words)'
y
%
但要注意:这依赖于一个称为“lazyio”的特性,该特性只与纯代码中的惰性技术有关。纯函数在默认情况下是懒惰的,您必须努力使其严格;IO在默认情况下是“严格IO”,您必须努力使其成为懒惰IO。一些库函数(特别是
interact
(h)getContents
,以及
readFile
)已经用于这项工作


从概念上讲,它只读取它需要的内容。但它可能会使用缓冲区来执行此操作:

$ yes | strace -feread,write ghc -e 'interact (head . words)'
...
[pid 61274] read(0, "y\ny\ny\ny\ny\ny\ny\ny\ny\ny\ny\ny\ny\ny\ny\ny\n"..., 8096) = 8096
[pid 61272] write(1, "y", 1y)            = 1
[pid 61272] --- SIGVTALRM {si_signo=SIGVTALRM, si_code=SI_TIMER, si_timerid=0, si_overrun=0, si_value={int=0, ptr=0}} ---
[pid 61272] write(5, "\376", 1)         = 1
[pid 61273] read(4, "\376", 1)          = 1
[pid 61273] +++ exited with 0 +++
[pid 61274] +++ exited with 0 +++
[pid 61276] +++ exited with 0 +++
+++ exited with 0 +++
这表明(在Linux系统上)程序将自己分割成多个线程,其中一个线程从stdin读取8KiB的数据,然后另一个线程输出第一个字。主要原因是反复阅读少量内容效率很低。异步源(如终端和套接字)可能会产生较少的数据量,但:

$ strace -f -e trace=read,write -e signal= ghc -e 'interact (head . words)'
...
hello program
Process 61594 attached
[pid 61592] read(0, "hello program\n", 8096) = 14
[pid 61590] write(1, "hello", 5hello)        = 5

在这种情况下,终端层在第一个换行符处完成读取,即使缓冲区仍然是8KiB大。由于这些数据足以识别第一个单词,因此无需进一步读取

从概念上讲,它只读取它需要的内容。但它可能会使用缓冲区来执行此操作:

$ yes | strace -feread,write ghc -e 'interact (head . words)'
...
[pid 61274] read(0, "y\ny\ny\ny\ny\ny\ny\ny\ny\ny\ny\ny\ny\ny\ny\ny\n"..., 8096) = 8096
[pid 61272] write(1, "y", 1y)            = 1
[pid 61272] --- SIGVTALRM {si_signo=SIGVTALRM, si_code=SI_TIMER, si_timerid=0, si_overrun=0, si_value={int=0, ptr=0}} ---
[pid 61272] write(5, "\376", 1)         = 1
[pid 61273] read(4, "\376", 1)          = 1
[pid 61273] +++ exited with 0 +++
[pid 61274] +++ exited with 0 +++
[pid 61276] +++ exited with 0 +++
+++ exited with 0 +++
这表明(在Linux系统上)程序将自己分割成多个线程,其中一个线程从stdin读取8KiB的数据,然后另一个线程输出第一个字。主要原因是反复阅读少量内容效率很低。异步源(如终端和套接字)可能会产生较少的数据量,但:

$ strace -f -e trace=read,write -e signal= ghc -e 'interact (head . words)'
...
hello program
Process 61594 attached
[pid 61592] read(0, "hello program\n", 8096) = 14
[pid 61590] write(1, "hello", 5hello)        = 5

在这种情况下,终端层在第一个换行符处完成读取,即使缓冲区仍然是8KiB大。由于这些数据足以识别第一个单词,因此无需进一步读取

多谢各位。我也很欣赏答案的深度,包括如何测试它。谢谢。我也欣赏答案的深度,包括如何测试它。