-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathhaskell-programming-language.xml
68 lines (48 loc) · 2.57 KB
/
haskell-programming-language.xml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
<?xml version="1.0"?>
<book version="5.0"
xmlns="http://docbook.org/ns/docbook"
xmlns:xlink="http://www.w3.org/1999/xlink">
<info>
<title>Haskell编程语言</title>
<author>
<personname>王欣</personname>
<email>[email protected]</email>
</author>
<releaseinfo>draft r0.1, 2020-05-23</releaseinfo>
</info>
<chapter>
<title>函数</title>
<sect1>
<title>递归子函数</title>
<para>在Haskell中,有多种方式实现递归子函数,除了在<code>let</code>语句和<code>where</code>语句中定义外,还可以利用<code>Data.Function.fix</code>函数实现。</para>
</sect1>
</chapter>
<chapter>
<title>惰性</title>
<para>惰性是Haskell一个重要特点,在编程实践中可以加以利用,但有时也需要注意规避。</para>
<sect1>
<title>迭代器</title>
<para>其他语言中的迭代器也具有惰性的特点,例如Rust中的<code>io::BufRead::lines</code>返回迭代器按行读取文件内容,对应到Haskell中则是<code>Data.Text.Lazy.lines . Data.Text.Lazy.IO.readFile</code>。</para>
</sect1>
<sect1>
<title>陷阱</title>
<para>例如以下代码,因为惰性的存在,导致与预期不一致:</para>
<programlisting>main = do
contents <- readFile "foo.txt"
writeFile "foo.txt" ("# " ++ contents)</programlisting>
<para><command>runghc foo.hs</command>会提示以下错误:</para>
<screen>foo.hs: foo.txt: openFile: resource busy (file is locked)</screen>
<para>原因是因为惰性计算,在执行<code>writeFile</code>时,<code>readFile</code>还没有结束,导致文件还处于打开状态。在<link xlink:href="https://wiki.haskell.org/Maintaining_laziness#Input_and_Output"/>有详细的讨论。</para>
<para>至于以上问题的一个解决方案,是利用<code>Data.Text.IO</code>中的<code>readFile</code>接口替代。</para>
</sect1>
</chapter>
<chapter>
<title>随机</title>
<para>在许多编程语言中,存在<code>shuffle</code>函数,可以用于打乱列表元素的顺序,Haskell并没有提供这样的函数,但可以通过random包实现,示例代码如下:</para>
<programlisting>shuffle :: [a] -> IO [a]
shuffle list = do
numbers <- mapM (const System.Random.randomIO) list :: IO [Int]
return (map snd (Data.List.sortOn fst (zip numbers list)))</programlisting>
<para>在<link xlink:href="https://wiki.haskell.org/Random_shuffle"/>中有更多实现可供参考。</para>
</chapter>
</book>