2016-09-22 14 views
6

したがって、Haskell seq関数は、最初のパラメータの評価を強制し、3番目のパラメータを返します。したがって、それは中置演算子です。式の評価を強制したい場合、直感的にそのような特徴は単項演算子になります。 bを返し、どのようにbの復帰のために構築するか、なぜ必要な値は、aであれば、代わりにHaskellのseqはどのように使用されていますか?

seq :: a -> b -> b 

のそれは、結果的に

seq :: a -> a 

だろう。明らかに、私はハスケルを考えていない。 :)

+1

[非常にフォーマットの悪い] 'foldl''の定義(https://wiki.haskell.org/Seq)を見ると、いくつかのレットバインド変数を厳密に評価したいと思うことがよくありますあなたの 'b'値に入る' a'の中で。 –

答えて

15

についてa `seq` bそれは「aを評価」ということはありませんが、あなたがbを評価するために行くときあなたにもaを評価するように、それは、ab間の依存関係を作成することを考えるための方法。

これは、たとえばa `seq` aが完全に冗長であることを意味します。aを評価すると、Haskellにaを評価するように指示しています。同じ論理では、ただ1つの引数を持つseq aは、単体でaを書くこととまったく違うものではありません。

何とかaと評価されているseq aを持っているだけで動作しません。問題は、seq a自体が評価されない可能性のある式であることです。たとえば、ネストされたいくつかのサンクの内部に深く存在する可能性があります。だから、seq aの式全体を評価するときには、それは関係なくなるでしょう。その時点では、aを評価するでしょう。

@厳密な折り畳み(foldl')での使用方法のRhymoidの例が良いです。私たちの目標は、最終的な結果を評価するとすぐに中間累積値(acc)が各ステップで完全に評価されるように折り目を書くことです。これは、累積値と再帰呼び出しの間seqを追加することによって行われます。

foldl' f z (x:xs) = 
    let z' = f z x in z' `seq` foldl' f z' xs 

あなたが最終的な結果にそれらのすべてを接続し、折り目でfの各アプリケーション間のseqの長鎖としてこれを可視化することができます。このようにして最終的な式(すなわち、リストを合計することによって得られる数)を評価すると、中間値(つまり、リストを折りたたむときの部分和)が厳密に評価されます。

+0

私は今、 'seq'によって作成された依存関係が、少なくとも' foldl'の場合には上記のように重複していると考えています。通常の 'foldl'は既に' z''に依存関係を課しています。 。そうみたいです。 – George

+2

@defaults(\ x y - > 1)undefined [2] 'は、' undefined'を評価しようとする代わりに、1と評価されます。比較すると、 'foldl''エラーを使用します。なぜなら、それはそれを評価するからです。 – chi

+7

@GeorgeあなたがHaskellには当てはまらない、他の言語で慣れ親しんだ特性の1つは、関数アプリケーションがアプリケーションのすべての引数を明らかに「使用」していないことです。特に、アプリケーション 'foldl 'f z' xs'が引数として' z 'を持つからといって、必ずしも 'foldl'の定義を調べることなく)' z''が使われることを意味します。これは、使用されている '' z ''に関するあなたの引数が落ちる場所です: '' z ''は関数の引数です。 –

関連する問題