2017-11-16 20 views
6

ハスケルでの印刷は純粋な関数です。なぜ、または、どうしてですか?私はそれが純粋な関数と同じ値を返すとは限らないためではないと思っています。Haskellは純粋な関数ですか?

+5

'print'は何を返しますか? –

+1

組み込みの不純な関数にはすべて、その名前に 'unsafe'という単語があります。だから、 'print'は純粋です。同じパラメータで同じ結果が返されます。 – 4castle

+0

@ 4castle必ずしもそうではありませんが、通常は「安全でない」とは、その関数が合計ではないということです。 – freestyle

答えて

2

純関数のタグ(同じ引数値で与えられた同じ結果値に常に評価され、意味論的に観察可能な副作用または出力を引き起こさない関数、たとえば、変更可能なオブジェクトまたは出力I/Oデバイスへ)し、印刷の種類に考える:。

putStrLn :: String -> IO() 

あなたがそこにトリックを見つけるでしょう、それは常にIO()を返し、そう... 、それは効果をもたらす。したがって、Referential Transparencyは純粋ではありません たとえば、getLineIO Stringを返しますが、純粋な関数でもあります。私が言うことをしようとしている何(@interjay貢献)、答えは質問の非常に近い依存することである:

値の問題では、IO()は常に同じ入力に対して同じIO()値になります。実行の問題について

そして

その IO()の実行が副作用を持っている可能性があるため、それは純粋ではない(この 場合には、画面に文字列を入れたので、罪のないように見えますが、あなたがここに@Benの素敵なアプローチをよりよく理解することができ、いくつかのIOはランチ核爆弾ができた、と は、その後のInt 42を返す)

"実際に を「純粋に」操作する方法を説明する方法はいくつかあります。 IOはまったく同じ状態のモナドのようですが、 の状態はあなたの プログラムの外の世界全体です; =(あなたのスタッフ - > IO DBThing関数は本当に余分な 隠された引数を受け取り、世界を受け取ります実際には別の世界と一緒に DBThingを返します;これはいつも異なる の世界で呼び出されます。そのため、同じStuffで呼び出されたときに別のDBThing値を返すことがあります。 )別の説明は、IO DBThing値自体が命令的プログラムであることです。 。あなたのHaskellのプログラムは、IOを行い不純なプログラム を返さないIOを、やっていない、完全に純粋な機能、およびHaskellのランタイムシステム(impurely)」それは返す プログラムを実行

そして@Erik Allik 次のとおりです。

タイプIOの値を返す

ので、Haskellの機能、実行時に実際に実行されている 機能ではありません - 。何 実行されますと、IOは、したがって、これらの機能は、実際に純粋であるが、 その値そのものであります戻り値は非purを表します。計算。

あなたはここにUnderstanding pure functions in Haskell with IO

+0

Sneaky Haskell :) – HFBrowning

+1

@HFBrowningその理由は何ですか? ...なぜモナドのルールなのか、それはみんながhaskellを愛している理由なのです。純粋な関数、純粋な関数、純粋な愛ahaahah –

+1

明らかにそれは型に必要なので常にIO()を返しますが、常にIO()の_same_値を返します。 – Lee

5

タイプIO Intの値が本当にIntではありませんそれらを見つけたことができます。これは、 "Haskellの実行時代、そのような方法でIntの値を生成してください"と読む紙のようなものです。たとえ最終的にランタイムによって生成されたIntが異なっていても、紙片は不活性であり、同じままです。

mainに割り当てることで、用紙をランタイムに送信します。 IOアクションがmainの方法ではなく、コンテナの中で衰えていない場合は、決して実行されません。

IOアクションを返す関数は、他のアクションと同様に純粋です。彼らは常に同じ紙を返します。これらの命令でランタイムが行うことは別の問題です。

彼らはは純粋」tをweren場合

foo :: (Int -> IO Int) -> IO Int 
foo f = let x = f 0 in liftA2 (+) x x 
+0

実行時に 'IO X' 'X'は実際には同じように表されます。コンパイラは 'IO X'がどのように振る舞うかについて特別なことを知っているだけです(そして、純粋な値がどう振る舞うかについての特別なこと - 違反する可能性のある仮定!これらの前提を使用して最適化されたコードを生成します。命令(すなわち、「紙片」)としてのIOのビューは依然として有用である。 「実行時の値」に関連するものではなく、「論理オブジェクトとしての値」に関するものと考えるべきです。 – user2407038

+2

@ user2407038 GHCでは、少なくともIO Xは非常に異なる表現をしています(https://hackage.haskell.org/package/base-4.10.0.0/docs/src/GHC.Base.html#line- 1197)である。 –

0

foo :: (Int -> IO Int) -> IO Int 
foo f = liftA2 (+) (f 0) (f 0) 

を変更する前に、私たちはよく考えなければならないだろうはい、printは純粋関数です。戻り値は、タイプIO()です。これは、渡された文字列を出力する一連のコードと考えることができます。渡す文字列ごとに、常に同じコードが返されます。

関連する問題