は、私は以下のレコードを持っていると言う:Haskellはフィールド名文字列に基づいてレコードフィールドを動的に設定しますか?
data Rec = Rec {
field1 :: Int,
field2 :: Int
}
私は関数を書くにはどうすればよい:
私はfieldName
引数に文字列「フィールド1」または「フィールド2」に渡すことができるような
changeField :: Rec -> String -> Int -> Rec
changeField rec fieldName value
とそれは関連フィールドを更新してもらえますか?私はData.Data
とData.Typeable
をここで使うものと理解していますが、私はこれらの2つのパッケージを理解することはできません。
私が見たことのあるライブラリの例は、cmdArgsです。以下は、このライブラリを使用する方法についてのブログ投稿からexcerpt次のとおりです。
{-# LANGUAGE DeriveDataTypeable #-}
import System.Console.CmdArgs
data Guess = Guess {min :: Int, max :: Int, limit :: Maybe Int} deriving (Data,Typeable,Show)
main = do
x <- cmdArgs $ Guess 1 100 Nothing
print x
今、私たちは、単純なコマンドラインパーサを持っています。いくつかのサンプルの相互作用は、次のとおりです。
$ guess --min=10
NumberGuess {min = 10, max = 100, limit = Nothing}
あなたはおそらくこれをしたくありません。 [レンズ](http://stackoverflow.com/questions/5767129/lenses-fclabels-data-accessor-which-library-for-structure-access-and-mutatio)について聞いたことがありますか?私は、これを達成する唯一の方法は、フィールド名を引数のインデックスと組み合わせ、 'gmapQi'などを使ってハックすることだと思います。 (これはあなたのレコード宣言に 'deriving(Typeable、Data)'を追加する必要があります。これは任意の型に対しては実行できません) – ehird
私はこれをしたいと思います。ユーザーがレコードを提供できるライブラリを作成したいと思います。ライブラリはテキストを解析することでレコードを作成できます。テキストには、設定したいレコードのフィールドへの参照が含まれます。 – Ana
このユーザー対応機能の実装をレコードフィールド名の内部実装の詳細に結びつけないようにすることをお勧めします。私はレンズベースのソリューションの2番目を提案しました。 Template Haskellを使ってレコードフィールド名から 'recMap'の作成を自動化することができます。 – ehird