7

Haskellに次のような関数があるかどうか誰かが知っていますか?

"Int" -> Int

"String" -> String

"Bool" -> Bool

すなわち。型コンストラクター名の文字列表現を受け取り、式とパターンの両方で実際の型コンストラクターに変換します。

編集:私の全体的な目標は、次のようなものを単純化することです。

transExp (Add exp1 exp2) vars
  = transExp exp1 vars ++ transExp exp2 vars ++ [IAdd]

transExp (Sub exp1 exp2) vars
  = transExp exp1 vars ++ transExp exp2 vars ++ [ISub]

単一のパターンマッチに変換するため、基本的にAddまたはSubを文字列に変換し、先頭に「I」を追加してから、タイプに変換し直します。

4

4 に答える 4

10

テンプレートHaskellやリフレクションシェナニガンを使用せずに、ケースAddSubケースを1つに結合するだけで、コードをリファクタリングするためのはるかに優れた方法があります。

data BinOp = Add | Sub | ...

data Expr = ...
          | BinOp BinOp Expr Expr
          | ...

transExp (BinOp op exp1 exp2) vars
    = transExp exp1 vars ++ transExp exp2 vars ++ [transOp op]
...

transOp Add = IAdd
transOp Sub = ISub

このように、データ型を使用して、二項演算子が関連しているという事実を直接表現しているため、同様の変換が行われます。BinOp Add exp1 exp2どこかに追加するための特別なケースを作成したい場合は、パターンマッチングをオンにすることができます。

于 2011-11-17T11:36:34.697 に答える
3

どのような文脈で?Template HaskellとがありData.Typeableますが、実際に役立つ答えを得るには、詳細を提供する必要があります。

于 2011-11-17T10:14:17.253 に答える
0

さて、ここに問題があります。

"String" -> String

Haskell-landでは、これ"String"は価値がStringありますがタイプであるため、ぎこちないものです。だからあなたはこれを試すかもしれません:

String -> a

これはあなたが望むことをしません。型注釈を読む方法を学ぶ必要があります。型署名を読むことができないと、Haskellでひどい障害を負うことになります。上記のタイプは、「文字列を教えてください。あなたが要求する任意のタイプの値を提供できます」という意味です。プレリュードにはこの署名付きの関数があり、それはと呼ばれerrorますが、これはあなたが望むものではありません。

これらの線に沿って何かが必要なようです。

String -> TypeRep

申し訳ありませんが、そのような機能はありません。 クラスTypeRepをインスタンス化しません。Read

ここで実際に何をしようとしていますか? あなたが実際に何をしようとしているのかを教えていただければ、この問題を解決しようとするのではなく、その問題を解決することができます。

于 2011-11-17T10:42:47.290 に答える
0

文字列は実行時データであり、型はコンパイル時に完全に解決される必要があるため、これを行うことはできません。あなたがおそらくあなたの例でできる最善のことは、重複のいくつかを排除するためのヘルパー関数です:

helper exp1 exp2 vars op = transExp exp1 vars ++ transExp exp2 vars ++ [op]
transExp (Add exp1 exp2) vars = helper exp1 exp2 vars IAdd
transExp (Sub exp1 exp2) vars = helper exp1 exp2 vars ISub

ただし、ケースの数によっては、これは実際には長期的にはあまり役に立たない場合があります。

一般に、パターンマッチングは型構造に対して実行されるものであるため、具体的な型コンストラクターに対してコンパイル型でスペルアウトする必要があります。これは、本当に堅固な静的型システムを使用するために支払う必要のある価格です。

于 2011-11-17T10:46:30.787 に答える