8

s はコンパイル中に効果的に削除されるためnewtype、サンクはなく、値のみです。を使用して WHNF を要求するとどうなりrseqますか? たとえば、

Sum (lengthyComputation :: Int) `using` rseq

は次のようにSum定義されます

newtype Sum a = Sum { getSum :: a }

評価されるlengthyComputationかどうか?信頼できるように、どこかに指定/文書化されていますか?


更新:私の疑問をより詳細に説明させてください。直観的に言うと、「newtypeは厳密なので、その WHNF は内部にラップされているものの WHNF であることは明らかです」。しかし、これは非常に不正確な近道であり、その理由はあまり明確ではないと思います。例を挙げましょう:

標準data型の場合、WHNF は、値の構築に使用されたコンストラクターがわかっている形式として定義できます。たとえば、持っていない場合はseq、独自に作成できます

seqMaybe :: Maybe a -> b -> b
seqMaybe Nothing  = id
seqMaybe _        = id

同様に、任意のdata型について、そのコンストラクターの 1 つでパターン マッチングを行うだけです。

では取りましょう

newtype Identity a = Identity { runIdentity :: a }

同様のseqIdentity関数を作成します。

seqIdentity :: Identity a -> b -> b
seqIdentity (Identity _)  = id

明らかに、ここで WHNF に強制されるものは何もありません。(結局のところ、どのコンストラクターが使用されたかは常にわかっています。) コンパイル後は、seqIdentityと同じになりconst idます。実際、seqIdentity内にラップされた値の評価を強制するようなポリモーフィックを作成することはできませんIdentity! a の WHNF a をnewtype単純に変更されていない値として定義することができ、それは一貫性があります。では、sに対して WHNF はどのように定義されているnewtypeのでしょうか。それとも、厳密な定義はなく、「中身の WHNF である」という動作は、単純に明らかなものとして想定されているのでしょうか。

4

1 に答える 1

8

レポートのデータ型の名前変更に関するセクションによると、

代数データ型とは異なり、newtype コンストラクター N は持ち上げられないため、N ⊥ は ⊥ と同じです。

ここ

Sum ⊥ = ⊥

ニュータイプの弱頭ノーマルフォームはラップタイプのWHNFであり、

Sum (lengthyComputation :: Int) `using` rseq

評価しlengthyComputationます (式全体が評価されると、単なるバインディング

let x = Sum (lengthyComputation :: Int) `using` rseq

もちろんそうではありませんが、それは newtype コンストラクターがなくても同じです)。

定義式は次のseqとおりです。

seq ⊥ b  =  ⊥
seq a b  =  b, if a ≠ ⊥

それゆえ

seq (Sum ⊥) b = ⊥

そして

seq (lengthyComputaton :: Int) b

これは (擬人化で申し訳ありません)が ⊥ でseqあるかどうかを調べるために必要です。lengthyComputation :: Intそのためには、 を評価する必要がありlengthyComputation :: Intます。


再更新:

newtypes はunlifted です。つまり、コンストラクターは意味的に (構文的にのみ) 値コンストラクターではありません。コンストラクターでのパターンマッチングは、厳密ではないコンストラクターnewtypeでのパターン マッチングとは対照的です。data与えられた

newtype Foo a = Foo { unFoo :: a }  -- record syntax for convenience below

「パターンマッチ」

function :: Foo a -> Bar
function (Foo x) = whatever x

と完全に同等です

function y = let x = unFoo y in whatever x

一致は常に成功し、何も評価しません。コンストラクターは型を強制するだけで、その「パターンマッチング」は値の型を強制解除します。

seqは魔法なので、Haskell では実装できません。newtype コンストラクターでの「パターン マッチング」は厳密ではないため、Haskell では上記のような型と同じことを行う関数を記述できますが、 (多形) にseqdata記述できseqMaybeません。newtypeラップされた型のコンストラクターで一致する必要がありますが、ポリモーフィックnewtypeの場合、それらはありません。

于 2012-12-02T13:00:48.657 に答える