-1

次の 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 で述べた理由により、アプローチ全体が維持できなくなります。

4

1 に答える 1

1

理論的には、自由変数(関数の外部からキャプチャされたラムダ項)なしでコンビネータ論理を使用できますが(ラムダ計算でリクエストを表現する方法です)、難解プログラミング言語のように、非常に非実用的で面倒なものでなければなりません。 。

コメントで指摘されているように、「値」は関数です(引数がなくても)。自由変数を使用しない場合の主な障害は、入出力関数が関数の外部にあるため、純粋な組み合わせプログラムはIOを実行できず、Haskell自体よりもさらに役に立たないことです(SPJによるとHaskellは使い物にならない:) )。さらに、ライブラリ関数がないままになります。これは、プログラミングではなく、一部の数学的な演習にのみ役立つ場合があります。

もう1つの質問は、関数の一部のサブセットでローカルで可能かどうかですが、GHCまたは他のHaskell実装でこれが可能かどうかは疑問です。

コンビネータ論理インタプリタの実装はいくつかありますが、Haskellを純粋なコンビネータにするための努力は見当たりません。

結論:この質問は、むしろ言語設計と基礎となる数学的形式の選択の領域に属します。Haskell(自由変数を持つラムダ計算に基づく)は、あなたが望むものとは明らかに異なります。Haskellにそのような制約を導入すると、Haskellは別の言語になりますが、コードの規律を観察して部分的に組み合わせることはできます。自由な「値」(引数なしの関数)に制限を導入することは数学的に無意味であるため、これを行うための組み込みのHaskellメカニズムが存在する可能性はほとんどありません。

于 2012-10-30T16:29:42.623 に答える