-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathghci.xml
More file actions
2454 lines (2034 loc) · 153 KB
/
ghci.xml
File metadata and controls
2454 lines (2034 loc) · 153 KB
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
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
<?xml version="1.0" encoding="UTF-8"?>
<chapter id="ghci">
<title>GHCiを使う</title>
<indexterm><primary>GHCi</primary></indexterm>
<indexterm><primary>interpreter</primary><see>GHCi</see></indexterm>
<indexterm><primary>interactive</primary><see>GHCi</see></indexterm>
<para>GHCi<footnote><para>「i」はinteractiveのiである</para></footnote>はGHCの対話環境であり、Haskellの式を対話的に評価したりプログラムを解釈実行したりできる。もしあなたが<ulink url="http://www.haskell.org/hugs/">Hugs</ulink><indexterm><primary>Hugs</primary></indexterm>に慣れ親しんでいるなら、GHCiの扱いにもすぐに慣れるだろう。しかしながら、GHCiはコンパイル済みコードをロードすることができ、また、GHCが提供する言語拡張の全て<footnote><para>ただし、現在のところ、<literal>foreign export</literal>を除く</para></footnote>をサポートする。<indexterm><primary>FFI</primary><secondary>GHCi support</secondary></indexterm><indexterm><primary>Foreign Function Interface</primary><secondary>GHCi support</secondary></indexterm>また、GHCiには対話的デバッガが含まれている。(<xref linkend="ghci-debugger"/>を見よ)</para>
<sect1 id="ghci-introduction">
<title>GHCiの紹介</title>
<para>GHCiセッションの例を見ていくことから始めよう。GHCiは<literal>ghci</literal>コマンドで起動することができる。</para>
<screen>
$ ghci
GHCi, version 6.12.1: http://www.haskell.org/ghc/ :? for help
Loading package ghc-prim ... linking ... done.
Loading package integer-gmp ... linking ... done.
Loading package base ... linking ... done.
Loading package ffi-1.0 ... linking ... done.
Prelude>
</screen>
<para>GHCiがプレリュードと標準ライブラリをロードするのに少し時間が掛かるかもしれない。その後、プロンプトが表示される。バナーにある通り、<literal>:?</literal>と打ち込めば利用可能なコマンド一覧と、それぞれの短い説明が得られる。これらの大部分はこれから説明する。また、全てのコマンドについての完全な文書が<xref linkend="ghci-commands" />にある。</para>
<para>プロンプトでは、Haskellの式を入力することができる。</para>
<indexterm><primary>prompt</primary><secondary>GHCi</secondary>
</indexterm>
<screen>
Prelude> 1+2
3
Prelude> let x = 42 in x / 9
4.666666666666667
Prelude>
</screen>
<para>GHCiは行全体を一つの式だと解釈し、それを評価する。式は複数の行に渡っていてはいけない。エンターキーが押されると、GHCiは即座にそれを評価しようとする。</para>
<!-- 訳注: 次の段落は削除されるべき -->
<para>Haskellでは、<literal>let</literal>式には<literal>in</literal>が続く。しかし、GHCiでは、式は<literal>IO</literal>モナドの中でも解釈され得るので、付属する<literal>in</literal>文のない<literal>let</literal>束縛は、上の例のように空行を使うことで示すことができる。</para>
</sect1>
<sect1 id="loading-source-files">
<title>ソースファイルをロードする</title>
<para>次のようなHaskellソースコードが<filename>Main.hs</filename>というファイルに置かれているとしよう。</para>
<programlisting>
main = print (fac 20)
fac 0 = 1
fac n = n * fac (n-1)
</programlisting>
<para><filename>Main.hs</filename>はどこでも好きなところに保存することができるが、カレントディレクトリ<footnote><para>GHCiをシェルから起動したのなら、GHCiのカレントディレクトリはシェルのそれと同じである。GHCiをWindowsの「スタート」メニューから起動したなら、カレントディレクトリはおそらく<filename>C:\Documents and Settings\<replaceable>user name</replaceable></filename>あたりになる。</para></footnote>以外の場所に保存した場合、GHCiでディレクトリを正しく変更する必要がある。</para>
<screen>
Prelude> :cd <replaceable>dir</replaceable>
</screen>
<para>ここで、<replaceable>dir</replaceable>は<filename>Main.hs</filename>を保存したディレクトリ(あるいはフォルダ)である。</para>
<para>HaskellのソースファイルをGHCiにロードするには、<literal>:load</literal>コマンドを使う。</para>
<indexterm><primary><literal>:load</literal></primary></indexterm>
<screen>
Prelude> :load Main
Compiling Main ( Main.hs, interpreted )
Ok, modules loaded: Main.
*Main>
</screen>
<para>GHCiは<literal>Main</literal>モジュールをロードし、プロンプトが「<literal>*Main></literal>」に変わった。これは、プロンプトに入力される式を評価するのに使われる文脈が、今ロードしたばかりの<literal>Main</literal>モジュールになったことを示すためのものである(<literal>*</literal>が何を意味するかについては<xref linkend="ghci-scope"/>で説明する)。つまり、これで<filename>Main.hs</filename>で定義された関数を含む式を入力できるようになったということである。</para>
<screen>
*Main> fac 17
355687428096000
</screen>
<para>複数のモジュールからなるプログラムをロードするのも同様に簡単である。「最上位の」モジュールの名前を<literal>:load</literal>コマンドに指定すれば良い(ヒント: <literal>:load</literal>は<literal>:l</literal>に短縮できる)。最上位のモジュールはふつう<literal>Main</literal>であるが、必ずしもそうである必要はない。GHCiは最上位のモジュールから直接・間接に必要とされているモジュールを見付け、それらを依存関係の順にロードする。</para>
<sect2 id="ghci-modules-filenames">
<title>モジュールとファイル名</title>
<indexterm><primary>modules</primary><secondary>and filenames</secondary></indexterm>
<indexterm><primary>filenames</primary><secondary>of modules</secondary></indexterm>
<para>GHCは<replaceable>M</replaceable>というモジュールがどのファイルにあるかをどのようにして知るのだろうか。GHCiは、<literal><replaceable>M</replaceable>.hs</literal>または<literal><replaceable>M</replaceable>.lhs</literal>というファイルを探すのである。したがって、大部分のモジュールでは、モジュール名とファイル名は一致しなければならない。一致しなかった場合、GHCiはモジュールを見つけ出すことができない。</para>
<para>この規則には一つの例外がある。<literal>:load</literal>を使ってプログラムをロードするとき、あるいは<literal>ghci</literal>を起動するとき、モジュール名ではなくファイル名を指定することができる。そのファイルはもし存在するならロードされ、どんなモジュールを含んでいても構わない。これは、複数の<literal>Main</literal>モジュールが一つのディレクトリにある場合、全てを<filename>Main.hs</filename>と呼ぶことはできないので、特に便利である。</para>
<para>ソースファイルを探すときの探索パスは、次に示すように、GHCiのコマンド行で<option>-i</option>を使って指定することができる。</para>
<screen>ghci -i<replaceable>dir<subscript>1</subscript></replaceable>:...:<replaceable>dir<subscript>n</subscript></replaceable></screen>
<para>あるいは、GHCiの中から<literal>:set</literal>コマンドを使って設定することもできる(<xref linkend="ghci-cmd-line-options"/>を見よ)<footnote><para>GHCiや<option>--make</option>モードでは<option>-i</option>オプションは<emphasis>ソース</emphasis>ファイルの探索パスを指定するのに対し、標準の一括コンパイルモードでは<option>-i</option>オプションはインターフェースファイルの探索パスを指定することに注意。<xref linkend="search-path"/>を見よ。</para></footnote>。</para>
<para>GHCiが上記のような方法で依存関係を追うことの帰結として、全てのモジュールにソースファイルがなければならない、というものがある。唯一の例外はパッケージ由来のモジュールで、これには<literal>Prelude</literal>や、<literal>IO</literal>、<literal>Complex</literal>といった標準ライブラリも含まれる。モジュールをロードしようとたときGHCiがソースファイルを見付けられなかった場合、たとえそのモジュールのオブジェクトファイルやインタフェースファイルがあったとしても、エラーメッセージが表示されるだろう。</para>
</sect2>
<sect2>
<title>ソースコードの変更と再コンパイル</title>
<indexterm><primary><literal>:reload</literal></primary></indexterm>
<para>ソースコードに変更を加えて、GHCiに再コンパイルさせたいときは、<literal>:reload</literal>コマンドを使えば良い。プログラムは必要に応じて再コンパイルされる。このとき、GHCiは依存関係の変化がないモジュールを実際に再コンパイルするのを避けようと最善を尽くす。これは一括コンパイル時に再コンパイルを避ける機構(<xref linkend="recomp"/>を見よ)と同じである。</para>
</sect2>
</sect1>
<sect1 id="ghci-compiled">
<title>コンパイル済みコードをロードする</title>
<indexterm><primary>compiled code</primary><secondary>in GHCi</secondary></indexterm>
<para>HaskellのソースモジュールをGHCiにロードしたとき、それはふつうバイトコードに変換され、解釈実行器を使って実行される。しかし、解釈実行されるコードをコンパイル済みコードと共に実行することもできる。実際、GHCiは起動するとふつう<literal>base</literal>パッケージのコンパイル済みのものをロードする(そのなかに<literal>Purelude</literal>がある)。</para>
<para>なぜコンパイル済みのコードを使う必要があるのだろうか。コンパイル済みコードは解釈実行されるコードに比べて大体10倍速いが、一方、生成するのに2倍の時間が掛かる(最適化が有効ならさらに長いかもしれない)のである。そのため、プログラムのあまり変更されない部分をコンパイルしておき、活発に開発されている部分には解釈実行器を使う、ということをするだけの価値がある。</para>
<para><literal>:load</literal>でソースモジュールをロードするとき、GHCiは対応するオブジェクトファイルを探し、可能ならソースコードの解釈実行よりも優先してそれを使う。例えば、A、B、C、Dという四つのモジュールからなるプログラムがあるとしよう。モジュールBとCはどちらもDのみをインポートしていて、AはBとCをインポートしている。</para>
<screen>
A
/ \
B C
\ /
D
</screen>
<para>Dをコンパイルして、その後プログラム全体をロードすると次のようになる。</para>
<screen>
Prelude> :! ghc -c -dynamic D.hs
Prelude> :load A
Compiling B ( B.hs, interpreted )
Compiling C ( C.hs, interpreted )
Compiling A ( A.hs, interpreted )
Ok, modules loaded: A, B, C, D.
*Main>
</screen>
<para>コンパイラのメッセージ中に、<literal>D</literal>についての行がない。これは、ソースファイルとその依存関係が、最後にコンパイルされたときから変更されていないため、コンパイルする必要ないからである。</para>
<para><literal>-dynamic</literal>フラグがGHCに与えられていることに注意せよ。GHCiは(対応しているプラットフォームなら)動的リンクされたオブジェクトコードを使うので、コンパイル済みコードをGHCiで使うなら、動的リンク用にコンパイルしておかなければならない。</para>
<para>いつでも、<literal>:show modules</literal>コマンドを使って、その時点でロードされているモジュールの一覧を表示することができる。</para>
<screen>
*Main> :show modules
D ( D.hs, D.o )
C ( C.hs, interpreted )
B ( B.hs, interpreted )
A ( A.hs, interpreted )
*Main></screen>
<para>ここでDを編集(あるいは編集したふりをする。これにはUnixの<literal>touch</literal>コマンドが便利である)すると、コンパイラはオブジェクトファイルを使うことができなくなる。既に古くなっているかもしれないからである。</para>
<screen>
*Main> :! touch D.hs
*Main> :reload
Compiling D ( D.hs, interpreted )
Ok, modules loaded: A, B, C, D.
*Main>
</screen>
<para>Dがコンパイルされたが、この例ではDのソースは実際には変更されていないので、インタフェースは同じままであり、そのため再コンパイル検査器がA、B、Cを再コンパイルする必要がないと判断したことに注意。</para>
<para>では他のモジュールをコンパイルしてみよう。</para>
<screen>
*Main> :! ghc -c C.hs
*Main> :load A
Compiling D ( D.hs, interpreted )
Compiling B ( B.hs, interpreted )
Compiling C ( C.hs, interpreted )
Compiling A ( A.hs, interpreted )
Ok, modules loaded: A, B, C, D.
</screen>
<para>Cのコンパイル済みの版が使われていない。これはどうしたことかというと、GHCではコンパイル済みのモジュールは別のコンパイル済みのモジュールにしか依存できないのである。この場合は、CがDに依存するが、Dにはオブジェクトファイルがないので、GHCiはCのオブジェクトファイルも利用しなかった。では、Dもコンパイルしてみよう。</para>
<screen>
*Main> :! ghc -c D.hs
*Main> :reload
Ok, modules loaded: A, B, C, D.
</screen>
<para>なにも起こらない!これは新たな教訓である。新しくコンパイルされたモジュールは<literal>:reload</literal>では使われない。<literal>:load</literal>が必要である。</para>
<screen>
*Main> :load A
Compiling B ( B.hs, interpreted )
Compiling A ( A.hs, interpreted )
Ok, modules loaded: A, B, C, D.
</screen>
<para>このようなオブジェクトファイルの自動ロードは混乱の原因になることがある。なぜなら、モジュールの最上位の、エクスポートされていない定義をプロンプトの式で使えるのは、そのモジュールが解釈実行されているときだけだからである(<xref linkend="ghci-scope"/>を見よ)。このため、解釈実行器を使ってモジュールをロードするようにGHCiに強制したいと思うことがあるかもしれない。これは、<literal>:load</literal>を使うときに、モジュール名またはファイル名の前に<literal>*</literal>を置くことで実現できる。例を挙げる。</para>
<screen>
Prelude> :load *A
Compiling A ( A.hs, interpreted )
*A>
</screen>
<para><literal>*</literal>が使われている場合、GHCiはコンパイル済みオブジェクトコードがあっても無視し、そのモジュールを解釈実行する。既にモジュールをいくつかオブジェクトコードとしてロードしていて、そのうち一つを解釈実行したいなら、全部を再ロードする代わりに、<literal>:add *M</literal>を使って、<literal>M</literal>が解釈実行されて欲しいことを指定することができる。(これによって別のモジュールも解釈実行されるかもしれないことに注意。これは、コンパイル済みモジュールが解釈実行モジュールに依存できないためである)。</para>
<para><literal>-fobject-code</literal>オプションを使うと、常にあらゆる物をオブジェクトコードにコンパイルし、決してインタプリタを使わないようにすることができる(<xref linkend="ghci-obj"/>を見よ)。</para>
<para>ヒント: GHCはコンパイル済みの版が最新であることが確かな場合しかコンパイル済みオブジェクトファイルを使わないので、大きいプロジェクトを扱っているときは、ときどき<literal>ghc --make</literal>を実行してプロジェクト全体をコンパイルし(例えば昼食を食べに行く前にね)、解釈実行器を使って作業を続けるというのが良い方法である。コードを変更すると、変更されたモジュールは解釈実行されるが、プロジェクト中のその他の部分は変わらずコンパイル済みのものが使われる。</para>
</sect1>
<sect1 id="interactive-evaluation">
<title>プロンプトで対話的に評価する</title>
<para>プロンプトに式を入力すると、GHCiは即座に評価して結果を印字する。
<screen>
Prelude> reverse "hello"
"olleh"
Prelude> 5+5
10
</screen>
</para>
<sect2 id="actions-at-prompt"><title>I/O動作とプロンプト</title>
<para>GHCiはプロンプトにおいて行うのは単なる式の評価だけではない。なんらかの<literal>a</literal>について<literal>IO a</literal>の型を持つものを入力すると、GHCiはそれをIO動作として<emphasis>実行</emphasis>するのである。
<screen>
Prelude> "hello"
"hello"
Prelude> putStrLn "hello"
hello
</screen>
これは、式の型を<literal>IO a</literal>に<emphasis>具体化</emphasis>することができる限り、その型がもっと一般的であっても動作する。例えば
<screen>
Prelude> return True
True
</screen>
さらに、次の場合には(そしてその場合に限り)、GHCiはIO動作の結果を印字する。
<itemizedlist>
<listitem><para>結果の型が<literal>Show</literal>のインスタンスである。</para></listitem>
<listitem><para>結果の型が<literal>()</literal>でない。</para></listitem>
</itemizedlist>
例えば、<literal>putStrLn :: String -> IO ()</literal>に注意すると、次のようになる。
<screen>
Prelude> putStrLn "hello"
hello
Prelude> do { putStrLn "hello"; return "yes" }
hello
"yes"
</screen>
</para></sect2>
<sect2 id="ghci-stmts">
<title>プロンプトで<literal>do</literal>記法を使う</title>
<indexterm><primary>do-notation</primary><secondary>in GHCi</secondary></indexterm>
<indexterm><primary>statements</primary><secondary>in GHCi</secondary></indexterm>
<para>GHCiは実際には単なる式ではなく<firstterm>文</firstterm>を受け付ける。そのため、値や関数を名前に束縛して、後で式や文の中で使うことができる。</para>
<para>GHCiプロンプトが受け付ける文の構文は、Haskellの<literal>do</literal>式における文の構文と全く同じである。ただし、こちらにはモナドの多重定義はない。プロンプトに入力される文は<literal>IO</literal>モナドの中になければならない。
<screen>
Prelude> x <- return 42
Prelude> print x
42
Prelude>
</screen>
<literal>x <- return 42</literal>という文は、「<literal>return 42</literal>を<literal>IO</literal>モナドの中で実行し、結果を<literal>x</literal>に束縛する」という意味である。以降、<literal>x</literal>を文の中で使う(例えば、上でしたように、値を印字する)ことができるようになる。</para>
<para><option>-fprint-bind-result</option>が設定されているなら、GHCiは次の場合に(そしてその場合に限り)、文の結果を印字する。
<itemizedlist>
<listitem>
<para>文が束縛ではないか、ただ一つの変数を束縛するモナド束縛(<literal>p <- e</literal>)である。</para>
</listitem>
<listitem>
<para>変数の型が多相的でなく、<literal>()</literal>でなく、<literal>Show</literal>のインスタンスである。</para>
</listitem>
</itemizedlist>
<indexterm><primary><option>-fprint-bind-result</option></primary></indexterm><indexterm><primary><option>-fno-print-bind-result</option></primary></indexterm>
</para>
<para>もちろん、非IOの式を<literal>let</literal>文を使って束縛することもできる。</para>
<screen>
Prelude> let x = 42
Prelude> x
42
Prelude>
</screen>
<para>この二種類の束縛のもう一つの違いは、モナド束縛(<literal>p <- e</literal>)が<emphasis>正格</emphasis>(<literal>e</literal>が評価される)のに対して、<literal>let</literal>形式では式がすぐには評価されないことである。</para>
<screen>
Prelude> let x = error "help!"
Prelude> print x
*** Exception: help!
Prelude>
</screen>
<para>モナド束縛と違って、<literal>let</literal>束縛では束縛された値が自動的に印字されることがないことに注意。</para>
<para>ヒント: <literal>let</literal>文を使って、プロンプトで関数を定義することもできる。</para>
<screen>
Prelude> let add a b = a + b
Prelude> add 1 2
3
Prelude>
</screen>
<para>しかし、複数の節からなる関数を定義したり、相互再帰的な関数を定義したりしようとすると、このやりかたはすぐ面倒になる。レイアウト規則が使えず、定義全体を、明示的な中括弧とセミコロンを使って一行で与えないといけないからだ。</para>
<screen>
Prelude> let { f op n [] = n ; f op n (h:t) = h `op` f op n t }
Prelude> f (+) 0 [1..3]
6
Prelude>
</screen>
<para>この問題を軽減するために、GHCiのコマンドを<literal>:{</literal>と<literal>:}</literal>で囲む(それぞれ一行使って)と、複数行に渡らせることができるようになっている。</para>
<screen>
Prelude> :{
Prelude| let { g op n [] = n
Prelude| ; g op n (h:t) = h `op` g op n t
Prelude| }
Prelude| :}
Prelude> g (*) 1 [1..3]
6
</screen>
<para>このような複数行コマンドは全てのGHCiコマンドについて用いることができ、<literal>:{</literal>と<literal>:}</literal>の間の行は単純に一行に繋げられて解釈される。よって、この行の集りは繋げられたときに単一の正しいコマンドになっていなければならず、レイアウト規則を使うことはできない<!--訳注: できる-->。複数行コマンドの主な目的は、モジュールのロードの代替にすることではなく、.ghciファイル(<xref linkend="ghci-dot-files"/>を見よ)での定義を見やすく、保守しやすくすることである。</para>
<para>文を評価または実行している間に発生した例外は、GHCiのコマンド行インタフェースによって捕捉され、印字される(例外について詳しくは、ライブラリ説明書の<literal>Control.Exception</literal>を見よ)。</para>
<para>束縛は、同じ名前の既存の束縛を覆い隠す。現在のモジュールの文脈でスコープにある実体も同様に覆い隠される。</para>
<para>警告: プロンプトで導入された束縛は一時的なもので、次に<literal>:load</literal>か<literal>:reload</literal>コマンドが実行されるまでしか存在しない。これらのコマンドが実行されると、一時的な束縛は全て失われる。ただし、<literal>:module</literal>での文脈の変更では失われない。一時的な束縛が新しい場所に移動するだけである。</para>
<para>ヒント: <literal>:show binding</literal>コマンドを使うと、その時点でスコープにある束縛の一覧を得ることができる。</para>
<screen>
Prelude> :show bindings
x :: Int
Prelude></screen>
<para>ヒント: <literal>+t</literal>オプションを有効にすると、GHCiは文によって束縛された全ての変数の型を表示するようになる。例えば、次のようにである。</para>
<indexterm><primary><literal>+t</literal></primary></indexterm>
<screen>
Prelude> :set +t
Prelude> let (x:xs) = [1..]
x :: Integer
xs :: [Integer]
</screen>
</sect2>
<sect2 id="ghci-multiline">
<title>複数行入力</title>
<para>上で言及した<literal>:{ ... :}</literal>構文による複数行入力の他に、GHCには<literal>:set +m</literal><indexterm><primary><literal>:set +m</literal></primary></indexterm>で有効になる複数行モードがある。このモードでは現在の文が終わっていない場合にGHCiが自動的にそれを検出し、さらに行を加えることを許す。複数行入力は空行で終わる。例を挙げる。</para>
<screen>
Prelude> :set +m
Prelude> let x = 42
Prelude|
</screen>
<para>この<literal>let</literal>文には続けて束縛を加えることができるので、GHCiはプロンプトを変更して、次の行が続きであることを示している。レイアウトが有効なので、この<literal>let</literal>に束縛を加えるには行頭を揃える必要があることに注意。</para>
<screen>
Prelude> :set +m
Prelude> let x = 42
Prelude| y = 3
Prelude|
Prelude>
</screen>
<para>通常通り、レイアウトの代わりに明示的な中括弧とセミコロンを使うこともできる。</para>
<screen>
Prelude> do {
Prelude| putStrLn "hello"
Prelude| ;putStrLn "world"
Prelude| }
hello
world
Prelude>
</screen>
<para>閉じ中括弧の後では、現在の文が終わったことをGHCiが知っているので、空行が必要ないことに注意。</para>
<para>複数行モードはモナドな<literal>do</literal>の文を入力するのに便利である。</para>
<screen>
Control.Monad.State> flip evalStateT 0 $ do
Control.Monad.State| i <- get
Control.Monad.State| lift $ do
Control.Monad.State| putStrLn "Hello World!"
Control.Monad.State| print i
Control.Monad.State|
"Hello World!"
0
Control.Monad.State>
</screen>
<para>複数行での操作中、ユーザは中断して最上位のプロンプトに戻ることができる。</para>
<screen>
Prelude> do
Prelude| putStrLn "Hello, World!"
Prelude| ^C
Prelude>
</screen>
</sect2>
<sect2 id="ghci-decls">
<title>型、クラスおよびその他の宣言</title>
<para>GHCiプロンプトではまた、Haskellの任意の最上位宣言を入力することができる。これには以下の各宣言が含まれる。<literal>data</literal>、<literal>type</literal>、<literal>newtype</literal>、<literal>class</literal>、<literal>instance</literal>、<literal>deriving</literal>、<literal>foreign</literal>。例を挙げる。</para>
<screen>
Prelude> data T = A | B | C deriving (Eq, Ord, Show, Enum)
Prelude> [A ..]
[A,B,C]
Prelude> :i T
data T = A | B | C -- Defined at <interactive>:2:6
instance Enum T -- Defined at <interactive>:2:45
instance Eq T -- Defined at <interactive>:2:30
instance Ord T -- Defined at <interactive>:2:34
instance Show T -- Defined at <interactive>:2:39
</screen>
<para>通常の値の束縛と同様に、後で定義されたものは古い定義を隠すので、定義を再入力することでそれの問題を修正したり拡張したりできる。ただし落とし穴が一つある。新しい宣言が古いものを隠すとき、古い定義を参照している別の宣言があるかもしれない。覚えておくべきなのは、この古い型はまだ存在し、この別の宣言はまだ古い型を参照しているということである。しかし、古い型と新しい型は同名であるが、GHCiはこれらを別々のものとして扱う。例を示す。</para>
<screen>
Prelude> data T = A | B
Prelude> let f A = True; f B = False
Prelude> data T = A | B | C
Prelude> f A
<interactive>:2:3:
Couldn't match expected type `main::Interactive.T'
with actual type `T'
In the first argument of `f', namely `A'
In the expression: f A
In an equation for `it': it = f A
Prelude>
</screen>
<para>古い、隠された方の<literal>T</literal>はGHCiによって<literal>main::Interactive.T</literal>と表示されている。これは、新しい<literal>T</literal>(単に<literal>T</literal>と表示される)と区別しようとしてこうなっている。</para>
<para>クラスや型族のインスタンス宣言は、単に「利用可能なインスタンスの一覧」に追加される。ただし例外が一つある。クラスインスタンスや型族インスタンスを再定義したいこともあるので、それぞれ頭部や左辺が同一であるインスタンスが過去にあった場合にはそれを<emphasis>置き換える</emphasis>。(<xref linkend="type-families"/>を見よ。)</para>
</sect2>
<sect2 id="ghci-scope">
<title>プロンプトで実際にスコープにあるのは何か</title>
<para>プロンプトに式を入力するとき、どの識別子や型がスコープにあるのだろうか。GHCiでは、式を評価する際の環境をどうやって構築するか、正確に指定することができる。以下のように。
<itemizedlist>
<listitem><para>
<literal>:load</literal>、<literal>:add</literal>、<literal>:reload</literal>の各コマンド(<xref linkend="ghci-load-scope"/>)。
</para></listitem>
<listitem><para>
<literal>import</literal>宣言(<xref linkend="ghci-import-decl"/>)。
</para></listitem>
<listitem><para>
<literal>:module</literal>コマンド(<xref linkend="ghci-module-cmd"/>)。
</para></listitem>
</itemizedlist>
</para>
<para><literal>:show imports</literal>は、どのモジュールの内容がスコープにあるかについて要約を表示する。</para>
<para>
ヒント: GHCiはスコープにある名前をtab補完する。たとえば、GHCiを起動して<literal>J<tab></literal>を打ち込むと、GHCiはそれを「<literal>Just </literal>」に展開する。
</para>
<sect3 id="ghci-load-scope">
<title>スコープ内容に対する<literal>:load</literal>の影響</title>
<para>
<literal>:load</literal>、<literal>:add</literal>、<literal>:reload</literal>の各コマンドがスコープに影響する。(<xref linkend="loading-source-files"/>および<xref linkend="ghci-compiled"/>)。単純な場合から始めよう。GHCiを開始すると、プロンプトは次のようになっている。
<screen>Prelude></screen>
これは、<literal>Prelude</literal>モジュールの全てのものが現在スコープにあるということを示している。可視な識別子は、ちょうど<literal>import</literal>宣言のないHaskellファイルで可視なものである。</para>
<para>ここでファイルをGHCiにロードすると、プロンプトは次のように変わる。</para>
<screen>
Prelude> :load Main.hs
Compiling Main ( Main.hs, interpreted )
*Main>
</screen>
<para>新しいプロンプトは<literal>*Main</literal>であり、これは、入力される式が、<literal>Main</literal>モジュールのトップレベルの文脈で評価されるということである。<!-- 今ロードしたばかりの --><literal>Main</literal>モジュールのトップレベルでスコープにあるものは、全てプロンプトでもスコープにある。(<literal>Main</literal>が明示的に隠していない限り、これにはおそらく<literal>Prelude</literal>も含まれる)</para>
<para>プロンプトにおける<literal>*<replaceable>module</replaceable></literal>という構文は、プロンプトから入力される式に対して、<replaceable>module</replaceable>の完全なトップレベルスコープが使われるということを示している。<literal>*</literal>がない場合、そのモジュールがエクスポートしているものだけが可視である。</para>
<para>注意: 技術的な理由から、GHCiは解釈実行されるモジュールについてしか<literal>*</literal>形式をサポートしない。そのため、コンパイル済みモジュールとパッケージのモジュールは、それがエクスポートしたものでしかプロンプトのスコープに寄与できない。GHCiがモジュールの解釈実行版を使っていることを確実にするには、モジュールをロードする時に<literal>*</literal>を加えれば良い。例えば<literal>:load *M</literal>のように。</para>
<para>一般に、<literal>:load</literal>コマンドが実行された後、直近にロードされた「ターゲット」モジュールに対するインポートが自動的にスコープに追加される。このとき、可能なら<literal>*</literal>形式が使われる。例えば、<literal>:load foo.hs bar.hs</literal>と入力したとき、<filename>bar.hs</filename>には<literal>Bar</literal>というモジュールがあるとすると、スコープは、<literal>Bar</literal>が解釈実行されているなら<literal>*Bar</literal>になり、<literal>Bar</literal>がコンパイル済みなら<literal>Prelude Bar</literal>になる。(GHCiは<literal>Prelude</literal>が指定されておらず、しかも<literal>*</literal>形式のモジュールが一つもないとき、自動的にそれを付け加える)。これらの自動追加されたインポートは<literal>:show imports</literal>で見ることができる。
<screen>
Prelude> :load hello.hs
[1 of 1] Compiling Main ( hello.hs, interpreted )
Ok, modules loaded: Main.
*Main> :show imports
:module +*Main -- added automatically
*Main>
</screen>
この自動追加されたインポートは、次に<literal>:load</literal>または<literal>:add</literal>または<literal>:reload</literal>を行なったときに別のものに置き換えられる。通常のインポートと同様に<literal>:module</literal>で削除することもできる。</para>
</sect3>
<sect3 id="ghci-import-decl">
<title><literal>import</literal>を使ったスコープ制御</title>
<para>扱えるのは単一のモジュールだけではない。GHCiは複数のモジュールのスコープを組み合わせることができ、このとき<literal>*</literal>が付く形式と<literal>*</literal>なしの形式を混合して用いることができる。GHCiはこれらのモジュールのスコープを全て組み合わせ、プロンプトのスコープとする。</para>
<para>モジュールをスコープに加えるには、通常のHaskellの<literal>import</literal>構文を使う。</para>
<screen>
Prelude> import System.IO
Prelude System.IO> hPutStrLn stdout "hello\n"
hello
Prelude System.IO>
</screen>
<para><literal>hiding</literal>節と<literal>as</literal>節を含めて、完全なHaskellのimport構文に対応している。プロンプトは現在インポートされているモジュールを示すが、<literal>hiding</literal>や<literal>as</literal>などの詳細は省略される。詳しい事情を知りたければ、<literal>:show imports</literal>を使うことができる。</para>
<screen>
Prelude> import System.IO
Prelude System.IO> import Data.Map as Map
Prelude System.IO Map> :show imports
import Prelude -- implicit
import System.IO
import Data.Map as Map
Prelude System.IO Map>
</screen>
<para><literal>Prelude</literal>のインポートがimplicitと標示されているのに注意。通常のHaskellモジュール内と同様に、明示的に<literal>Prelude</literal>をインポートすればそちらが優先される。</para>
<para>複数のモジュールがスコープにあるとき、特に複数の<literal>*</literal>形式のモジュールがあるときは、名前の衝突が起こりやすい。Haskellでは、名前の衝突は曖昧な識別子が使われたときのみ報告されると定められており、GHCiもプロンプトで入力される式についてこれに倣っている。</para>
</sect3>
<sect3 id="ghci-module-cmd">
<title><literal>:module</literal>コマンドを使ったスコープ制御</title>
<para>スコープを操作するもう一つの方法は<literal>:module</literal>コマンドである。構文は以下である。
<screen>
:module <optional>+|-</optional> <optional>*</optional><replaceable>mod<subscript>1</subscript></replaceable> ... <optional>*</optional><replaceable>mod<subscript>n</subscript></replaceable>
</screen>
<para><literal>+</literal>を使えばモジュールが現在のスコープに加えられ、<literal>-</literal>では削除される。<literal>+</literal>も<literal>-</literal>もない場合は、指定されたモジュール群がそのままで現在のスコープになる。この形式を使って、しかも<literal>Prelude</literal>を含めなかった場合、GHCiは暗黙の<literal>Prelude</literal>インポートを自動的に追加する。</para>
<para><literal>:module</literal>コマンドは、通常の<literal>import</literal>宣言では実現できないことをする方法を提供する。</para>
<itemizedlist>
<listitem>
<para><literal>:module</literal>は、モジュールに付く<literal>*</literal>修飾子に対応する。これは、単にモジュールがエクスポートしているものだけでなく、そのモジュールの完全な最上位スコープを開く。</para>
</listitem>
<listitem>
<para><literal>:module -M</literal>構文を使うと、文脈からモジュールを<emphasis>削除</emphasis>することができる。<literal>import</literal>構文は(Haskellモジュール内と同じく)累積的なので、これがスコープから一部を取り除く唯一の方法である。</para>
</listitem>
</itemizedlist>
</para>
</sect3>
<sect3 id="ghci-import-qualified">
<title>修飾名</title>
<para>手間をすこし省くことができるように、GHCiのプロンプトは、全てのパッケージの全てのモジュールと、現在GHCiにロードされている全てのモジュールについて、暗黙の<literal>import qualified</literal>宣言があるかのように振る舞う。これは<option>-fno-implicit-import-qualified</option><indexterm><primary><option>-fno-implicit-import-qualified</option></primary></indexterm>というフラグで無効にできる。</para>
</sect3>
<sect3>
<title><literal>:module</literal>と<literal>:load</literal></title>
<para><literal>:module</literal>と<literal>:load</literal>は似たようなことをするように思えるかもしれない。どちらも、モジュールをスコープに入れるのに使うことができる。しかし、この二つには非常に重要な違いがある。GHCiは、以下の二つのモジュール集合を意識する。</para>
<itemizedlist>
<listitem>
<para>現在<emphasis>ロードされている</emphasis>モジュールの集合。この集合は、<literal>:load</literal>、<literal>:add</literal>、<literal>:reload</literal>によって変更され、<literal>:show modules</literal>で見ることができる。
</para>
</listitem>
<listitem>
<para>現在<emphasis>スコープにある</emphasis>モジュールの集合。この集合は<literal>import</literal>と<literal>:module</literal>によって変更される。また、上述のように<literal>:load</literal>、<literal>:add</literal>、<literal>:reload</literal>の後に自動的に変更が加えられる。スコープにあるモジュールの集合は<literal>:show imports</literal>で見ることができる。</para>
</listitem>
</itemizedlist>
<para>(<literal>:module</literal>や<literal>import</literal>で)スコープに入れることができるのは、(a)ロードされているモジュールか、(b)GHCiが知っているパッケージに入っているモジュールだけである。<literal>:module</literal>を使ってロードされていないモジュールをスコープに入れようとすると「<literal>module M is not loaded</literal>」というメッセージが表示されることがある。</para>
</sect3>
</sect2>
<sect2>
<title><literal>:main</literal>コマンドと<literal>:run</literal>コマンド</title>
<para>
プログラムがコンパイルされ実行されるとき、コマンド行引数にアクセスするために<literal>getArgs</literal>関数を使うことができる。しかし、ghciでテストをしているときは、コマンド行引数を単純に<literal>main</literal>関数の引数として渡すことはできない。<literal>main</literal>関数は直接には引数をとらないからである。
</para>
<para>
その代わり、<literal>:main</literal>コマンドを使うことができる。これは、とにかくスコープにある<literal>main</literal>を、引数がコマンド行から渡されたのと同じようにして実行する。例えば、次のようにである。
</para>
<screen>
Prelude> let main = System.Environment.getArgs >>= print
Prelude> :main foo bar
["foo","bar"]
</screen>
<para>スペースなどの文字を含む引数は、引用符に入れることができ、Haskellの文字列と同じように扱われる。また、Haskellのリスト構文をそのまま使うこともできる。</para>
<screen>
Prelude> :main foo "bar baz"
["foo","bar baz"]
Prelude> :main ["foo", "bar baz"]
["foo","bar baz"]
</screen>
<para>最後に、<literal>-main-is</literal>フラグや<literal>:run</literal>コマンドを使えば、その他の関数を呼ぶことができる。</para>
<screen>
Prelude> let foo = putStrLn "foo" >> System.Environment.getArgs >>= print
Prelude> let bar = putStrLn "bar" >> System.Environment.getArgs >>= print
Prelude> :set -main-is foo
Prelude> :main foo "bar baz"
foo
["foo","bar baz"]
Prelude> :run bar ["foo", "bar baz"]
bar
["foo","bar baz"]
</screen>
</sect2>
<sect2>
<title><literal>it</literal>という変数</title>
<indexterm><primary><literal>it</literal></primary>
</indexterm>
<para>式(正確には束縛文でない文)がプロンプトに入力されると、GHCiはその値を暗黙のうちに変数<literal>it</literal>に束縛する。例えば、次のようにである。</para>
<screen>
Prelude> 1+2
3
Prelude> it * 2
6
</screen>
<para>実際に何が起こっているかというと、GHCiは入力された式を型検査し、もし<literal>IO</literal>型でなければ、それを次のように変形するのである。式<replaceable>e</replaceable>は
<screen>
let it = <replaceable>e</replaceable>;
print it
</screen>
になり、これがIO動作として実行される。</para>
<para>そのため、元の式の型は<literal>Show</literal>のインスタンスでなければならない。そうでなければ、GHCiは次のように文句を言う。</para>
<screen>
Prelude> id
<interactive>:1:0:
No instance for (Show (a -> a))
arising from use of `print' at <interactive>:1:0-1
Possible fix: add an instance declaration for (Show (a -> a))
In the expression: print it
In a 'do' expression: print it
</screen>
<para>このエラーメッセージから、内部でどういう変換が起こっているかを少しうかがい知ることができる。</para>
<para>式の型がなんらかの<literal>a</literal>について<literal>IO a</literal>である場合は、<literal>it</literal>は<literal>IO</literal>動作の結果(これの型は<literal>a</literal>である)に束縛される。例えば、以下。</para>
<screen>
Prelude> Time.getClockTime
Wed Mar 14 12:23:13 GMT 2001
Prelude> print it
Wed Mar 14 12:23:13 GMT 2001
</screen>
<para>IO型の<replaceable>e</replaceable>についてなされる変換は、
<screen>
it <- <replaceable>e</replaceable>
</screen>
である。
</para>
<para>新しい式を評価するたびに<literal>it</literal>は新しい値で覆い隠され、<literal>it</literal>の古い値は失われることに注意。</para>
</sect2>
<sect2 id="extended-default-rules">
<title>GHCiにおける型のデフォルト化</title>
<indexterm><primary>Type default</primary></indexterm>
<indexterm><primary><literal>Show</literal> class</primary></indexterm>
<para>
次のGHCiセッションを考えてみよう。
<programlisting>
ghci> reverse []
</programlisting>
GHCiは何をするべきか。厳密に言うと、このプログラムは曖昧である。<literal>show (reverse [])</literal>(ここでGHCiが計算するのはこれである)の型は<literal>Show a => String</literal>であり、これをどのように表示するかは<literal>a</literal>の型に依存する。例えば、
<programlisting>
ghci> reverse ([] :: String)
""
ghci> reverse ([] :: [Int])
[]
</programlisting>
のようになる。しかし、利用者が型を指定しなければならないというのは面倒なので、GHCiはHaskellの型デフォルト化規則(Haskell 2010レポートの4.3.4節)を以下のように拡張している。標準の規則では、個々の型変数<literal>a</literal>について制約の集まり<literal>(C1 a, C2 a, ..., Cn a)</literal>を考え、次の条件が満たされたとき、この型変数をデフォルト化する。
<orderedlist>
<listitem><para>型変数<literal>a</literal>が他のどの制約にも現れない。</para></listitem>
<listitem><para><literal>Ci</literal>が全て標準のクラスである。</para></listitem>
<listitem><para><literal>Ci</literal>のうち、少なくとも一つが数値クラスである。</para></listitem>
</orderedlist>
GHCiのプロンプトでは、あるいはGHCで<literal>-XExtendedDefaultRules</literal>フラグが与えられている場合、以下の変更が適用される。
<itemizedlist>
<listitem><para>上の規則2が次のように緩和される: <literal>Ci</literal>が<emphasis>全て</emphasis>単引数の型クラスである。</para></listitem>
<listitem><para>上の規則3が次のように緩和される: <literal>Ci</literal>のうち、少なくとも一つが数値クラスである<emphasis>か、<literal>Show</literal>であるか、<literal>Eq</literal>であるか、<literal>Ord</literal>である</emphasis>。</para></listitem>
<listitem><para>単位型<literal>()</literal>が、型のデフォルト化の際に通常試す型のリストの先頭に追加される。</para></listitem>
</itemizedlist>
最後の点は、例えば、このプログラムに影響する。
<programlisting>
main :: IO ()
main = print def
instance Num ()
def :: (Num a, Enum a) => a
def = toEnum 0
</programlisting>
これが、<literal>0</literal>ではなく<literal>()</literal>を表示する。型が<literal>Integer</literal>でなく<literal>()</literal>にデフォルト化されるためである。</para>
<para>
この変更の理由は、これによって<literal>IO a</literal>の動作が<literal>IO ()</literal>にデフォルト化されるので、ghciがこれらを走らせたときに結果を表示する必要がなくなることである。これは<literal>printf</literal>の場合に特に重要である。<literal>printf</literal>には<literal>IO a</literal>を返すインスタンスがあるが、これが返せるのは<literal>undefined</literal>だけである。(インスタンスがこの型なのは、printfがクラスシステムの拡張を必要としないようにである)。このため、もし型が<literal>Integer</literal>にデフォルト化されるなら、ghciはprintfを実行する時にエラーを発生させることになる。</para>
<para>計算を扱う式のモナドが可能なら<literal>IO</literal>にデフォルト化される事については<xref linkend="actions-at-prompt"/>を見よ。</para>
</sect2>
<sect2 id="ghci-interactive-print">
<title>デフォルト以外の対話表示関数を使う</title>
<para>[<emphasis role="bold">バージョン7.6.1の新機能</emphasis>]
デフォルトでは、GHCiはプロンプトに入力された式の結果を関数<literal>System.IO.print</literal>を使って表示する。これの型シグネチャは<literal>Show a => a -> IO ()</literal>であり、値を<literal>show</literal>で<literal>String</literal>に変換することで動作する。
</para>
<para>ある種の状況では、これは理想的でない。たとえば出力が長い場合や、非ascii文字のある文字列を含んでいる場合である。
</para>
<para>フラグ<literal>-interactive-print</literal>を使うと、何らかの制約<literal>C</literal>について<literal>C a => a -> IO ()</literal>という型を持つ任意の関数を、評価された式を表示するための関数として指定することができるようになる。その関数はロードされているモジュールのいずれか、あるいは登録済みモジュールのいずれかにあれば良い。
</para>
<para>例として、以下の特別な表示モジュールがあるとしよう。
<programlisting>
module SpecPrinter where
import System.IO
sprint a = putStrLn $ show a ++ "!"
</programlisting>
関数<literal>sprint</literal>は表示された値の最後に感嘆符を付ける。次のコマンドでGHCiを走らせると、
<programlisting>
ghci -interactive-print=SpecPrinter.sprinter SpecPrinter
</programlisting>
対話セッションが開始され、そこでは値が<literal>sprint</literal>で表示される。
<programlisting>
*SpecPrinter> [1,2,3]
[1,2,3]!
*SpecPrinter> 42
42!
</programlisting>
</para>
<para>デフォルト以外の表示関数は、例えば、木構造や入れ子の構造をより読み易く表示するために使うことができる。
</para>
<para>
<literal>-interactive-print</literal>フラグは、GHCを<literal>-eモード</literal>で走らせるときにも使える。
<programlisting>
% ghc -e "[1,2,3]" -interactive-print=SpecPrinter.sprint SpecPrinter
[1,2,3]!
</programlisting>
</para>
</sect2>
</sect1>
<sect1 id="ghci-debugger">
<title>GHCiデバッガ</title>
<indexterm><primary>debugger</primary><secondary>in GHCi</secondary>
</indexterm>
<para>GHCiは単純な命令的スタイルのデバッガを搭載していて、実行中の計算を停めて変数の値を確かめることができる。このデバッガはGHCiに統合されており、デフォルトで有効になっている。デバッグ機能を使うのにフラグは必要ない。一つ、重要な制限があって、ブレークポイントとステップ実行は解釈実行されているモジュールでしか使えない。コンパイル済みコードはデバッガからは見えない<footnote><para>パッケージにはコンパイル済みコードしか入っていないので、パッケージをデバッグするにはそのソースを見つけてきて直接ロードするしかないことに注意。</para></footnote>。</para>
<para>このデバッガは以下のものを提供する。
<itemizedlist>
<listitem>
<para>プログラム中の関数定義や式に<firstterm>ブレークポイント</firstterm>を設定する能力。その関数が呼ばれたとき、あるいはその式が評価されたとき、GHCiは実行を中断してプロンプトに戻る。そこで、実行を続ける前に、局所変数の値を調べることができる。</para>
</listitem>
<listitem>
<para><firstterm>ステップ実行</firstterm>ができる。評価器は、簡約をだいたい一回行うごとに実行を一時停止し、局所変数を調べることができるようにする。これはプログラムのあらゆる地点にブレークポイントを設定するのと同様である。</para>
</listitem>
<listitem>
<para>実行を<firstterm>追跡モード</firstterm>で行うことができる。この場合、評価器は、発生した評価ステップをすべて記憶するが、実際のブレークポイントに達するまで実行を停止しない。一旦停止した後で、この評価ステップの履歴を調べることができる。</para>
</listitem>
<listitem>
<para>例外(パターン照合の失敗や<literal>error</literal>など)をブレークポイントとして扱うことができる。これによって、プログラム中の例外の発生源を突き止めることが容易になる。</para>
</listitem>
</itemizedlist>
</para>
<para>現在のところ、“スタックトレース”を得る手段は提供されていないが、追跡と履歴の機能が有用な次善策になっていて、これらで十分エラー発生時の状況を知ることができることがしばしばある。例えば、例外が投げられたときに自動的にブレークするようにすることが可能で、これは例外がコンパイル済みコードで投げられた場合にも有効である。(<xref linkend="ghci-debugger-exceptions"/>を見よ)</para>
<sect2 id="breakpoints">
<title>ブレークポイントと変数内容の表示</title>
<para>全体を通した例としてクイックソートを使おう。コードは以下の通り。</para>
<programlisting>
qsort [] = []
qsort (a:as) = qsort left ++ [a] ++ qsort right
where (left,right) = (filter (<=a) as, filter (>a) as)
main = print (qsort [8, 4, 0, 3, 1, 23, 11, 18])
</programlisting>
<para>まず、このモジュールをGHCiにロードする。</para>
<screen>
Prelude> :l qsort.hs
[1 of 1] Compiling Main ( qsort.hs, interpreted )
Ok, modules loaded: Main.
*Main>
</screen>
<para>ここで、qsortの二番目の等式の右辺にブレークポイントを設定する。</para>
<programlisting>
*Main> :break 2
Breakpoint 0 activated at qsort.hs:2:15-46
*Main>
</programlisting>
<para><literal>:break 2</literal>というコマンドは、直近にロードされたモジュール(この場合<literal>qsort.hs</literal>)の2行目にブレークポイントを設定するものである。詳しく言うと、その行にある完全な部分式のうちもっとも左側にあるものが選ばれる。この場合<literal>(qsort left ++ [a] ++ qsort right)</literal>である。</para>
<para>さて、プログラムを実行してみる。</para>
<programlisting>
*Main> main
Stopped at qsort.hs:2:15-46
_result :: [a]
a :: a
left :: [a]
right :: [a]
[qsort.hs:2:15-46] *Main>
</programlisting>
<para>ブレークポイントのところで実行が中断した。プロンプトが変わって、現在ブレークポイントで停止していることと、その場所が<literal>[qsort.hs:2:15-46]</literal>であることを示している。場所をさらに明確にするには、<literal>:list</literal>コマンドが使える。</para>
<programlisting>
[qsort.hs:2:15-46] *Main> :list
1 qsort [] = []
2 qsort (a:as) = qsort left ++ [a] ++ qsort right
3 where (left,right) = (filter (<=a) as, filter (>a) as)
</programlisting>
<para><literal>:list</literal>コマンドは、現在のブレークポイントのまわりのコードを表示する。出力デバイスが対応しているなら、注目している部分式が太字で強調される。</para>
<para>ブレークポイントの置かれた式の各自由変数(<literal>a</literal>と<literal>left</literal>と<literal>right</literal>)について、その束縛がGHCiに用意されている<footnote><para>元々、自由変数だけでなくスコープにあるあらゆる変数の束縛を用意していたが、これが性能にかなりの影響を与えることが分かった。そのため、現在は自由変数のみに制限している。</para></footnote>。さらに、この式の結果についての束縛(<literal>_result</literal>)も用意される。これらの変数は、GHCi上で普通に定義する変数と同じである。つまり、プロンプトに打ち込む式の中で使ったり、<literal>:type</literal>を使って型を問うたりできる。ただし、一つ重要な相違点があって、これらの変数は不完全な型しか持たないかもしれない。例えば、<literal>left</literal>の値を表示しようとすると次のようになる。</para>
<screen>
[qsort.hs:2:15-46] *Main> left
<interactive>:1:0:
Ambiguous type variable `a' in the constraint:
`Show a' arising from a use of `print' at <interactive>:1:0-3
Cannot resolve unknown runtime types: a
Use :print or :force to determine these types
</screen>
<para>原因は、<literal>qsort</literal>が多相関数であって、GHCiが型情報を実行時に保持しないので、型変数に関係した自由変数の実行時の型を決定することができないことだ。これにより、プロンプトで<literal>left</literal>を表示しようとすると、GHCiは<literal>Show</literal>のどのインスタンスを使うべきか判断できず、上のエラーを出力する。</para>
<para>幸いにも、デバッガには<literal>:print</literal>という汎用印字コマンドが搭載されている。このコマンドで、変数の実行時の値を調べ、その型を再構築することができる。これを<literal>left</literal>に対して試してみると次のようになる。</para>
<screen>
[qsort.hs:2:15-46] *Main> :set -fprint-evld-with-show
[qsort.hs:2:15-46] *Main> :print left
left = (_t1::[a])
</screen>
<para>これでは大したことは分からない。何が起きたかというと、<literal>left</literal>が未評価の計算(中断された計算、<firstterm>サンク</firstterm>ともいう)に束縛されており、しかも<literal>:print</literal>は決して評価を強制しないのだ。これは、ブレークポイントで<literal>:print</literal>を使って値を調べるとき、望ましくない副作用を起こさずに済むようにするためだ。評価を強制しないので、プログラムが通常と異なる結果を与えることもないし、例外が発生することもないし、無限ループや別のブレークポイント(<xref linkend="nested-breakpoints"/>)に遭遇することもない。<literal>:print</literal>は、サンクをforceする代わりに、各サンクをアンダースコアから始まる新しい変数(ここでは<literal>_t1</literal>)に束縛する。</para>
<para><literal>-fprint-evld-with-show</literal>というフラグは、<literal>:print</literal>が可能な限り既存の<literal>Show</literal>インスタンスを再利用するようにするものである。これが起こるのは、対象の変数の中身が完全に評価済みの時だけである。</para>
<para>変数の評価状態を変えても構わない場合、<literal>:print</literal>の代わりに<literal>:force</literal>を使うことができる。<literal>:force</literal>コマンドは、サンクに遭遇する度に評価を強制するが、この点を除いて<literal>:print</literal>とまったく同じように振る舞う。</para>
<screen>
[qsort.hs:2:15-46] *Main> :force left
left = [4,0,3,1]
</screen>
<para>ここで、<literal>:force</literal>が<literal>left</literal>の実行時の値を調べたので、この型が再構築された。この再構築の結果は次のようにして見ることができる。</para>
<screen>
[qsort.hs:2:15-46] *Main> :show bindings
_result :: [Integer]
a :: Integer
left :: [Integer]
right :: [Integer]
_t1 :: [Integer]
</screen>
<para><literal>left</literal>の型が分かっただけでなく、他の部分的な型もすべて解決されている。よって、例えば<literal>a</literal>の値を問い合わせることができる。</para>
<screen>
[qsort.hs:2:15-46] *Main> a
8
</screen>
<para>式全体の評価を<literal>:force</literal>で強制するのでなく、個々のサンクを評価したい場合、Haskellの<literal>seq</literal>が便利かもしれない。例えば以下のように使う。</para>
<screen>
[qsort.hs:2:15-46] *Main> :print right
right = (_t1::[Integer])
[qsort.hs:2:15-46] *Main> seq _t1 ()
()
[qsort.hs:2:15-46] *Main> :print right
right = 23 : (_t2::[Integer])
</screen>
<para>ここでは、サンク<literal>_t1</literal>だけを評価し、これでリストの頭部が分かった。尾部は別のサンクで、<literal>_t2</literal>に束縛された。ここでは<literal>seq</literal>関数は少々使いにくいので、<literal>:def</literal>を使ってもっと良いインタフェースをつけると良いかもしれない。(後は読者への練習問題としよう!)</para>
<para>最後に、現在の実行を再開することができる。</para>
<screen>
[qsort.hs:2:15-46] *Main> :continue
Stopped at qsort.hs:2:15-46
_result :: [a]
a :: a
left :: [a]
right :: [a]
[qsort.hs:2:15-46] *Main>
</screen>
<para>実行は、前に停止した点から再開し、同じブレークポイントで再び停止した。</para>
<sect3 id="setting-breakpoints">
<title>ブレークポイントを設定する</title>
<para>ブレークポイントを設定する方法はいくつかある。おそらくもっとも簡単な方法は最上位の関数の名前を使うことだろう。</para>
<screen>
:break <replaceable>identifier</replaceable>
</screen>
<para><replaceable>identifier</replaceable>は最上位の関数の名前(修飾名も使える)である。ただし、この関数の定義されているモジュールが、現在GHCiにロードされており、さらに解釈実行されていなければならない。ブレークポイントは関数の本体、関数が完全に適用されたがパターン照合が行われる前の点に設定される。</para>
<para>行番号(と列番号)でブレークポイントを設定することもできる。</para>
<screen>
:break <replaceable>line</replaceable>
:break <replaceable>line</replaceable> <replaceable>column</replaceable>
:break <replaceable>module</replaceable> <replaceable>line</replaceable>
:break <replaceable>module</replaceable> <replaceable>line</replaceable> <replaceable>column</replaceable>
</screen>
<para>ブレークポイントを特定の行に設定する場合、GHCiは、その行で始まりその行で終わる部分式の中でもっとも左側にあるものを選ぶ。二つの完全な部分式が同じカラムから始まっているなら長い方が選ばれる。その行に完全な部分式が無い場合、その行で始まっている部分式の中でもっとも左側にあるものが選ばれる。それも失敗したら、その行を一部か全部覆う式の中でもっとも右側にあるものが選ばれる。</para>
<para>ブレークポイントを特定の行の特定のカラムに設定する場合、GHCiはその地点を含む式の中で最小のものを選ぶ。注意: GHCは、TAB文字を、現れた場所に関わらず幅1とみなす。言い換えれば、カラム数を数えるのではなく文字を数えている。これはある種のエディタの振る舞いと整合するが、そうでないエディタもある。最善なのはそもそもソースコード中でタブ文字を使わないことである。(<xref linkend="options-sanity"/>中の<option>-fwarn-tabs</option>を見よ)</para>
<para>モジュールが省略された場合、直近にロードされたモジュールが使われる。</para>
<para>ブレークポイントを設定できない部分式もある。単一の変数は通常ブレークポイント位置とはみなされない。(ただし、その変数が関数定義かラムダかcaseの選択肢の右辺である場合は除く)。大まかに、ブレークポイントであるのは、全ての簡約基と、関数やラムダの本体、caseの選択肢、束縛文である。通常let式はブレークポイントでないが、その本体は常にブレークポイントである。そのletで束縛された変数の値を調べたいと思うのが普通だからである。</para>
</sect3>
<sect3>
<title>ブレークポイントを一覧・削除する</title>
<para>現在有効にされているブレークポイントの一覧は<literal>:show breaks</literal>で表示できる。</para>
<screen>
*Main> :show breaks
[0] Main qsort.hs:1:11-12
[1] Main qsort.hs:2:15-46
</screen>
<para>ブレークポイントを削除するには、<literal>:show breaks</literal>コマンドの出力にある数字を与えて<literal>:delete</literal>コマンドを使えば良い。</para>
<screen>
*Main> :delete 0
*Main> :show breaks
[1] Main qsort.hs:2:15-46
</screen>
<para>全てのブレークポイントを一度に削除するには、<literal>:delete *</literal>とすれば良い。</para>
</sect3>
</sect2>
<sect2 id="single-stepping">
<title>ステップ実行</title>
<para>ステップ実行は、プログラムの実行を可視化する偉大な方法であり、バグの原因を同定する手段としても有用である。<literal>:step</literal>コマンドを使うと、プログラム中の全てのブレークポイントが有効にされ、次のブレークポイントに達するまで実行される。<literal>:steplocal</literal>とすれば、現在のトップレベル関数の中にあるブレークポイントのみ有効にする。同様に、<literal>:stepmodule</literal>とすると現在のモジュール中にあるブレークポイントのみ有効にする。例えば以下のようになる。</para>
<screen>
*Main> :step main
Stopped at qsort.hs:5:7-47
_result :: IO ()
</screen>
<para><literal>:step <replaceable>expr</replaceable></literal>コマンドは、<replaceable>expr</replaceable>のステップ実行を開始する。<replaceable>expr</replaceable>が省略された時は、現在のブレークポイントからステップ実行する。<literal>:steplocal</literal>と<literal>:stepmodule</literal>も同様に動作する。</para>
<para>ステップ実行中には<literal>:list</literal>が特に便利で、自分がどこにいるか知ることができる。</para>
<screen>
[qsort.hs:5:7-47] *Main> :list
4
5 main = print (qsort [8, 4, 0, 3, 1, 23, 11, 18])
6
[qsort.hs:5:7-47] *Main>
</screen>
<para>実際、GHCiには、ブレークポイントに達したときに決まったコマンドを実行する方法があるので、自動的に<literal>:list</literal>するようにできる。</para>
<screen>
[qsort.hs:5:7-47] *Main> :set stop :list
[qsort.hs:5:7-47] *Main> :step
Stopped at qsort.hs:5:14-46
_result :: [Integer]
4