2016-02-04 9 views
10
Prelude> let a = 3 
Prelude> :sprint a 
a = _ 
Prelude> let c = "ab" 
Prelude> :sprint c 
c = _ 

なぜそれは常に_を印刷しますか?私は:sprintコマンドのセマンティクスを得ていません。なぜ:sprintは常に "_"を出力しますか?

+0

は、配列C()'の後に 'てみスプリントC 'はあなた' Cを与えます= 'a':_' ...最後の質問に投稿したリンク – Carsten

答えて

10

Haskellは怠惰な言語です。結果が「必要」になるまで結果を評価しません。

今、ちょうどの印刷の値はすべて「必要」になります。言い換えれば、GHCiに式を入力すると、結果が出力され、結果がすべて評価されます。通常はそれがあなたが望むものです。

sprintコマンド(これはGHCi機能であり、Haskell言語には含まれていません)では、この時点で評価された値の量を確認できます。例えば

Prelude> let xs = [1..] 
Prelude> :sprint xs 
xs = _ 

だから、私たちはxsを宣言し、それが現在未評価です。

Prelude> head xs 
1 
Prelude> :sprint xs 
xs = 1 : _ 

ここで、GHCiはリストの頭を評価しましたが、それ以上のことはありません。

Prelude> take 10 xs 
[1,2,3,4,5,6,7,8,9,10] 
Prelude> :sprint xs 
xs = 1 : 2 : 3 : 4 : 5 : 6 : 7 : 8 : 9 : 10 : _ 

これで、最初の10個の要素が評価されましたが、それ以上は残ります。 (xs無限リストあるので、それは驚くことではありません。)

あなたは他の式を構築し、何が起こっているかを確認するために一度に少しを評価することができます。これはGHCiデバッガの一部です.GHCiデバッガでは、一度に1つずつコードをステップ実行できます。特にコードが無限ループに巻き込まれている場合は、printはGHCiをロックする可能性があるため、何もしたくないです。しかし、あなたはまだ何が起こっているのかを見たいと思っています。したがってsprintはこれまで評価されたものを見ることができます。

+10

備考: '[1 ..]'は多型であるため、 'head xs'の後であっても':sp xs'は '_'を生成する可能性があります。 'let xs = [1. ..] :: [Integer]'これを修正します。 – Zeta

6

ハスケルは怠惰です。必要になるまで物事を評価しません。

GHCi sprintコマンド(Haskellの一部ではなく、インタープリタのデバッグコマンド)は、評価を強制することなく式の値を出力します。あなたは

let a = 3 

を書くとき

あなたは、右側の式に新しい名前aを結合するが、Haskellはまだそのことを評価しません。したがって、sprintと入力すると、式がまだ評価されていないことを示す値として_が出力されます。

これを試してみてください:

let a = 3 
:sprint a -- a has not been evaluated yet 
print a -- forces evaluation of a 
:sprint a -- now a has been evaluated 
+9

を 'let a = 3'にするともっと複雑になります(これを試してください) - デフォルトでは' a'は 'a :: Num a => a'そしてあなたの場合は常に ':sprint'から' _'になります - IMOの 'String'の例は、' let a = 3'を使う場合には – Carsten

+5

のように感じるのに適しています。 'let a = 3 :: Int'を混乱させないようにしましょう。また、この動作がGHC 7.8で変更されていることに注意してください。古いバージョンでは、この文で型を書く必要はありませんでした。 予想通り'。 – epsilonhalbe

3

は、私は少し遅れだが、私は同様の問題があった:

λ: let xs = [1,2,3] 
xs :: Num t => [t] 
λ: :sprint xs 
xs = _ 
λ: print xs 
λ: :sprint xs 
xs = _ 

この問題は、多型の値に固有のものです。あなたは-XNoMonomorphismRestriction有効GHCiのを持っている場合はが本当に/力xsを評価することはありません、それが唯一の/力の専門分野を評価します: `::

λ: :set -XMonomorphismRestriction 
λ: let xs = [1,2,3] 
xs :: [Integer] 
λ: print xs 
λ: :sprint xs 
xs = [1,2,3] 
+2

これは、 'xs'のような「オーバーロードされた」値にのみ適用されます。変数を持つ型を持ち、それらの型の型制約を持つもの。これは、ほとんどの場合、このように動作するリテラル番号を含む例に過ぎません。残念ながら、数字は学習中に遊ぶべき明白なものです。ブール値( 'True'、' False'、 '&&'、 'and'など)を使って遊んでいれば、' NoMonomorphismRestriction'や明示的な型名を指定しても、ほとんどすべてが同じように動作します。 – Ben

関連する問題