次の haskell プログラムを考えてみましょう:
g::Int
g = 300
func::Int->Int
func arg = arg + g
main = do
print (func 4)
「func」はその計算でグローバル変数 g を使用しているため、私はこのプログラムが特に好きではありません。また、私のプログラムで記述されたすべての関数が、必要な計算を実行するために必要なすべての要素を引数として指定することを目指したいと考えています (つまり、何も関数外が使用されます)。
私の質問はこれです:引数リストで定義されていない変数を使用する関数をghcに拒否させる方法はありますか? (純粋な規律に頼るよりも)...
[編集] : 次のことも考慮してください。
main.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]))
[EDIT 4] : EDIT3 のプログラムに関して、内部の「divisibleRec」は関数の引数として渡されないため、divisibleRec のような再帰的な使用も例外である必要があります。
また、多くの機能を連鎖させると、このルールは維持できなくなります。上記のプログラムでは、それほど悪くはありませんでした。「divisible x divisibleRec」があっただけですが、プログラムが大きくなると、すべての関数を 1 か所で効果的にチェーンする必要があるため、上記のスキームは維持できなくなります....
[編集 5] : この質問を最初に投稿したとき、関数と変数を別のレベルで表示していました。ただし、関数を変数と同じレベルで扱う場合、「プログラムで記述されたすべての関数は、必要な計算を実行するために必要なすべての要素を引数として指定する (つまり、関数の外では何も使用されない)」という制限は、以下を使用する関数を意味します。他の関数は、これらの他の関数を引数として渡す必要があります。その後、Edit4 で述べた理由により、アプローチ全体が維持できなくなります。