2016-11-27 34 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可能是指不同的变量从一个调用到下一个,那么答案是否定的。在这个定义中,y总是指向同一个变量(在Haskell中,它指的是相同的,不可变的值),它可以通过对程序的静态分析来确定,并且不能动态重新定义。

[[编辑:正如@Jon Purdy指出的那样,有一个Haskell扩展支持一种动态范围的形式,以下列举使用相同函数打印各种动态范围的本地值。

{-# 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 

的edit--]

对于惰性计算--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..] - 只需向上计数1,2,3,...永远)将进入无限循环,并且take函数会永远不会被调用。在第二个例子中,如果评估是严格的,当定义x时,不仅在我们试图打印其第二个组件之后,会发生除零错误。

+0

动态范围变量有一个扩展:'ImplicitParams'。例如,如果你有'pr ::(?currentOutputHandle :: Handle,Show a)=> a - > IO(); pr x = hPrint?currentOutputHandle x',那么你可以用例如本地重定向输出。 'let?currentOutputHandle =在pr“foo”'中的stderr。 –

+0

你是对的!几个小时前我只是在看这个扩展而没有建立连接。 –