-1

让我们考虑以下haskell程序:

g::Int
g = 300

func::Int->Int
func arg = arg + g

main = do
  print (func 4)

我不是特别喜欢这个程序,因为“func”在其计算中使用全局变量 g,我希望我的程序中编写的所有函数都将执行必要计算所需的所有元素指定为参数(即没有函数外使用)

我的问题是:有没有办法让 ghc 拒绝使用未在参数列表中定义的变量的函数?(而不必依赖纯粹的纪律)......

[编辑]:还要考虑以下几点:

主.hs:

import MyMod

func::Int->Int
func arg = arg + g

main = do
  print (func 4)

MyMod.hs

module MyMod where

g::Int
g = 300

[EDIT2]:我猜如果函数只能使用在参数列表中定义的变量,那么人们将不得不为以下事情做出例外(?):

g::Int
g = 300

h::Int
h = 400

i::Int
i = g + h

[EDIT3]:对于 nm 以响应“尝试编写具有这些限制的完整程序,该程序具有多个函数”(限制是函数只能使用在其参数列表中声明的变量)。当然必须有例外,在这种情况下,主要是例外。这个例子改编自比较 Haskell 和 C 计算素数的速度

divisibleRec :: Int -> Int -> Bool
divisibleRec i j 
  | j == 1         = False 
  | i `rem` j == 0 = True 
  | otherwise      = divisibleRec i (j-1)

divisible::Int->(Int -> Int -> Bool)-> Bool
divisible i fn= (fn i (i-1))

main :: IO()
main = print(length([ x | x <- [2..1000], (divisible x divisibleRec) == False]))

[编辑 4]:关于 EDIT3 中的程序,在 divisibleRec 中的递归使用也必须是一个例外,因为内部的“divisibleRec”不作为函数的参数提供。

当我们将许多功能链接在一起时,此规则也变得无法维护。在上面的程序中它并不算太糟糕,我们只有“divisible x divisibleRec”,但是随着我们有更大的程序,上面的方案变得无法维护,因为我们实际上必须将所有函数链接在一个地方......

[编辑 5]:当我最初发布这个问题时,我正在查看不同级别的函数和变量。但是,当您将函数视为变量时,因此限制“在我的程序中编写的所有函数都将执行必要计算所需的所有元素指定为参数(即不使用函数之外的任何内容)”意味着使用其他函数必须将这些其他函数作为参数传递,然后由于 Edit4 中提到的原因,整个方法变得不可维护。

4

1 回答 1

1

从理论上讲,您可以使用没有自由变量(从函数外部捕获的 lambda 项)的组合逻辑(这就是您的请求用 lambda 演算表达的方式),但它必须非常不切实际和繁琐,就像深奥的编程语言.

正如评论中所指出的,任何“值”都是一个函数(即使没有参数)。我看到不使用自由变量的主要障碍是任何输入/输出函数都在你的函数之外,所以纯组合程序不能做任何 IO,甚至比 Haskell 本身更无用(根据 SPJ 说 Haskell 是没用的:))。此外,您没有任何库函数,这些函数可能只对一些数学练习有用,而不是编程。

另一个问题是它是否可能在本地,在某些功能子集中,但我怀疑 GHC 或任何其他 Haskell 实现是否允许这样做。

一些组合逻辑解释器的实现,但我没有看到让 Haskell 成为纯组合的努力。

结论:这个问题属于语言设计和基础数学形式选择的领域。Haskell(基于带有自由变量的 lambda 演算)绝对不同于您想要的。将这样的约束引入 Haskell 将使它成为另一种语言,尽管您可以观察代码中的纪律以使其部分具有组合性。对自由“值”(无参数函数)引入限制在数学上毫无意义,因此不太可能有内置的 Haskell 机制来执行此操作。

于 2012-10-30T16:29:42.623 回答