2016-11-27 5 views
-3

私は概念的にこれらのすべてが何であるか理解しています。MLとHaskellでそれらを実装する方法のコード例がほしいと思っています。mlとhaskellでスタティックスコープ、ダイナミックスコープ、およびレイジー評価を実装する方法は?

+3

「実装する」とはどういう意味ですか?静的スコープ、動的スコープ、遅延評価のコードサンプルが必要ですか?また、これらの機能を備えたmlやHaskellでインタープリタを実装しますか?どちらの場合でも、問題は少し広いです。 – Alec

+0

http://okmij.org/ftp/Computation/dynamic-binding.html – coredump

+0

@Alec最初のオプション –

答えて

2

Haskell変数(最上位レベルの定義、パターン内の変数など)はすべて静的に有効です。たとえば、プログラム:

y = "global value" 
f = print y 
g = let y = "local value" in f 

main = g 

は「グローバル値」を出力します。 gの定義では、関数fが「再定義」yの後で使用されても、この再定義はfが定義されたyの静的(AKA語彙的)スコープ定義を使用するfの定義には影響しません。

ダイナミックスコープを「実装」したい場合は、実際に何を意味するのかを具体的に説明する必要があります。あなたのような、プレーンHaskellで関数を書くことができれば、あなたが迷っている場合:

addY :: Int -> Int 
addY x = x + y 

yは1つのコールから次へと別の変数を参照するかもしれないというように、その後、答えはノーです。この定義では、yは、常に同じ変数(Haskellでは同じ、不変の値を意味する)を参照します。これはプログラムの静的解析によって決定でき、動的に再定義することはできません。しかし、@ Jon Purdyは、ダイナミックスコープの形式をサポートするHaskell拡張機能があることを指摘しています。これは、次のように、同じ関数でさまざまな動的スコープのローカル値を出力するようになります。遅延評価のためedit--]

{-# LANGUAGE ImplicitParams #-} 
f :: (?y :: String) => IO() 
f = print ?y 
g = let ?y = "g's local value" in f 
h = let ?y = "h's local value" in f 
main = do 
    g    -- prints g's local value 
    h    -- prints h's local value 
    let ?y = "main's local value" in f -- prints main's value 

--end、例えば以下は、対話のGHCiセッションに入力された多くの例がある:

take 3 [1,2..] -- gives [1,2,3] 

let x = (15^2, 6 `div` 0) 
fst x    -- gives 225 
let y = snd x 
y     -- *** Exception: divide by zero 

最初に評価が厳格であれば、無限リスト[1,2..]を完全に評価しようと試みると([1..]と書くこともできます)、無限ループに入り、take関数は決して呼ばれることはありません。 2番目の例では、評価が厳密であれば、xが定義されたときに、2番目のコンポーネントを印刷しようとするだけでなく、ゼロ除算が発生します。

+0

動的スコープ付き変数の拡張子はImplicitParamsです。たとえば、 'pr ::(?currentOutputHandle :: Handle、Show a)=> a - > IO();とすると、 pr x = hPrint?currentOutputHandle x'を指定すると、出力をローカルにリダイレクトすることができます。 'let?currentOutputHandle = stderrをpr" foo "'に入れます。 –

+0

あなたは正しいです!そして、私は数時間前に接続を行わずにこの拡張機能を調べていました。 –

関連する問題