2016-08-17 11 views
3

私はhaskell bookを使っていますが、:sprint xはxの要素を表示するのに使われていると評価されていますが、要素は表示されていません'_'によって)。本の中で提供されている例の方法:スプリントとリストの評価がhaskellで動作する

一つ、

Prelude> let blah = enumFromTo 'a' 'z' 
Prelude> :sprint blah 
blah = _ 

Prelude> take 1 blah 
"a" 
Prelude> :sprint blah 
blah = 'a' : _ 

が異なる入力してテストするために、私はGHCiの中でこれをしなかった: -

prelude> let b = [1,2,3,4,5] 
prelude> :sprint b 
b = _ 
prelude> take 1 b 
[1] 
prelude> :sprint b 
b = _ 

万一最後で:sprint bのない出力コマンドはb = 1 : _です。take 1 bコマンドを使用するときは、単一​​のリスト項目とcons演算子のみを評価するためです。しかし、それは上の出力を示しています。どのように、なぜこれが起こっていますか?出力は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 : _ 

さて、私の最初の推測が、あるそれはので、私は二つのリストを構築しています方法のですか? 1つは範囲と明示的にその要素を述べることによって範囲を使用しています(cons ':'コンストラクタをその要素に対して再帰的に使用してリストを作成します)

答えて

6

:sprintの動作はややこしいことがあります。この場合、xの種類を見て:それはポリモーフィックなので

> :t x 
x :: Num t => [t] 

、生産される実際の値は、あなたが必要とNumの特定のインスタンスに依存します。したがって、xは、要素に必要な型を特定できるときに、リスト[1,2,3,4,5]を生成する関数のように機能します。

今、あなたはあなたがこれを試すので、「OK、Iが多型ではないリストを作ります」、と思うかもしれない:

> let x = [1,2,3,4,5 :: Int] 
> :t x 
x :: [Int] 
> :sprint x 
x = [1,2,3,4,5] 

は一体何?あなたがそれについて考えるなら、これは理にかなっています。リストが何であるかをghciに明示しました。それを評価し、後でそれを再評価することはできないのではない。 (これはとにかく無駄だろう)しかし、我々はX上の機能をマップしようとするのは、何が起こるか見てみましょう:

> let y = map (+1) x 
> :sprint y 
y = _ 
> take 1 y 
[2] 
> :sprint y 
y = 2 : _ 

期待と同じように!

希望に役立ちます。遅延テストは、Haskellに関する重要な問題の1つです(重要になったとき)。

+2

':set -XMonomorphismRestriction'を実行すると、最初の問題が解消されることになるかもしれません。 ':sprint'の使用例をいくつか示します。 * ParallelとConcurrent Haskell *の本では、ghciの中でデフォルトの '-XNoMonomorphismRestriction'を使う前に、この問題を引き起こします。おそらく ':sprint'を手に入れる前に、常にそれをオフにしたり、署名に慣れさせたりするべきでしょう。 – Michael

+0

先端に感謝します。 –

関連する問題