2

Haskell で「変数」の名前と値を出力したいとします。名前はコンパイル時に認識されます。次の例よりも良い方法はありますか?

module V
(e, c, eV, h, hbar, nm, k, viewAllConstants) where
import Text.Printf
c = 2.99792458e8::Double
e = exp(1)
eV = 1.602176565e-19
h = 6.62606957e-34
hbar = h/(2*pi)
nm = 1e-9
k = 1.3806488e-23
viewAllConstants = do
    putStr ((\a b -> (foldl (++) "" ( zipWith (++) a (map (printf " = %.2e\n") b))))
        ["c", "e", "eV", "h", "hbar", "nm", "k"]
        [c, e, eV, h, hbar, nm, k] )

回答に実際のコード例 (runhaskell) を投稿してください!

4

4 に答える 4

3

@PeterHallが言ったように:

Lisp では、データとコードの区別が曖昧で、実行時にすべてが検査可能で動的です。Haskell では、すべての型とバインディング名がコンパイル時に消去されるため、大量の最適化が可能になります。

つまり、名前は実行時にわかりません。

さらに、これらは「変数」ではなく、定数、または前述のようにバインディングです。このため、バインディングの名前は変更されないため、バインディングの名前にアクセスできても意味がありません。

@MathematicalOrchid が示唆したように、Haskell ソリューションのテンプレートが存在する可能性がありますが、それは比較的有用である可能性があります。

バインディングを印刷するより良い方法については、これを試してください:

import Control.Monad (forM_)

viewAllConstants = forM_ (\(a, b) -> putStrLn (a ++ " = " ++ show b)) 
                   $ zip ["c", "e", "eV", "h", "hbar", "nm", "k"] 
                         [ c,   e,   eV,   h,   hbar,   nm,   k ]
于 2015-05-11T18:08:37.577 に答える
2

あなたが本当に欲しいものについて少し混乱していると思います。識別子の名前cはただ"c"; 印刷しても問題ありません。

あなたが本当に望んでいるのは、モジュール内の と の間の重複を排除することだと思い["c", "e", "eV", "h", "hbar", "nm", "k"]ます[c,e,eV,h,hbar,nm,k]。具体的には、どのようにそれを行うつもりですか?次に、Haskell で動作するかどうかについて話します。

おそらく、どちらか、あるいは両方に行き着くでしょう。

  1. の欠如eval。list を保持している場合は、["c", "e", "eV", "h", "hbar", "nm", "k"]これらの文字列を評価して、対応する変数の値を見つけることができます。プログラムに Haskell インタープリターを潜在的に埋め込むことはできますが、他の人が指摘しているように、実行時に名前"c", , ... からそれらの値へのマッピングが必ずしも存在するわけではないため、文字列から値。"e""c"2.99792458e8

  2. 参照透過性。リストを保持して、そこから文字列, , ...[c,e,eV,h,hbar,nm,k]を復元する魔法の方法を期待できます。しかし、それも不可能です。は単なる Double のリストであり、 であるため、 もあり、後者から抽出する方法はありません。"c""e"[c,e,eV,h,hbar,nm,k]c = 2.99792458e8[c,e,eV,h,hbar,nm,k] = [2.99792458e8,e,eV,h,hbar,nm,k]"c"

于 2015-05-11T20:37:46.127 に答える
2

Haskell で「変数」の名前と値を出力したいとします。名前はコンパイル時に認識されます。

名前は一部のスコープでは知られていますが、他のスコープでは知られていません。これは重要です。サンプルコードを見てみましょう:

module V (e, c, eV, h, hbar, nm, k, viewAllConstants) where

c = 2.99792458e8
e = exp(1)
eV = 1.602176565e-19
h = 6.62606957e-34
hbar = h/(2*pi)
nm = 1e-9
k = 1.3806488e-23

viewAllConstants = do
    putStr (foldl (++) "" (map ("\n" ++)
                    ( zipWith (++) ["c", "e", "eV", "h", "hbar", "nm", "k"]
                        (map ((" = " ++) . show) [c,e,eV,h,hbar,nm,k])
                    )

                )
        )

putStrfoldlmapzipWithおよびshowは、GHC に付属するモジュールで定義された関数であり、プログラムとは別にコンパイルされます。これらの関数は、変数の名前を知る方法がありません。渡されるのは値だけです。

Peter Hall のコメントに反して、これは Haskell と Lisp の違いではないことに注意してください。Lisp では、プロシージャへの引数は、シンボルではなく値への参照によって渡されます。Lisp 関数は、Haskell の関数よりも引数の名前を認識していません。

また、どちらの言語でも、任意の式を引数として関数に渡すことができます。これらは、呼び出しサイトの変数にバインドされていない値です。

于 2015-05-11T21:41:58.533 に答える