JSONオブジェクトを取得し、その中のすべての文字列値を変更して新しいJSONオブジェクトを返す関数を作成しようとしています。これまでのところ、私のコードは次のとおりです。ハスケルのJSONデータ構造を再帰的に変更します。
applyContext :: FromJSON a => a -> a
applyContext x =
case x of
Array _ -> map applyContext x
Object _ -> map applyContext x
String _ -> parseValue x
_ -> x
しかし、コンパイラは、第二case
ライン文句:
Couldn't match expected type `[b0]' with actual type `a'
`a' is a rigid type variable bound by
the type signature for:
applyContext :: forall a. FromJSON a => a -> a
at app\Main.hs:43:17
私はmap
は、リスト上で動作するように意図されているため、つまり推測しているが、私は持っているでしょう代わりにData.HashMap.Lazy.map
を使用することを期待していました。これは、そのタイプが実際にその場合のものであるからです。私は明示的にその機能を使用する場合、私はそれが他のケースのために動作しないので、私はその程度のa
を制約していないことからも、理にかなって
Couldn't match expected type `HashMap.HashMap k0 v20' with actual type `a'
を取得します。私はこれで十分な明示的な型をスローすれば、動作させることができると思うが、もっとシンプルにすべきだと感じている。この関数を書く慣用的な方法は何ですか、あるいはこれが良い場合は、型を正しく取得する最も単純な方法は何でしょうか?
あなたがいない 'Data.HashMap.Lazy.map'、map''呼び出します。 Haskellは間違った型の引数を指定したからといって二度目に推測しようとしません。 – chepner
慣用的アプローチはタイプから始まり、「これは理にかなっていますか?私が知る限り、それはしません。最小限のようで、 'a'に' ToJSON'制約も必要です。まずは、「Value - > Value」型の関数を記述し、次に任意の型と「Value」の間で変換を行う第2の関数を記述します。そうすることで、どちらの制約が必要なのかが明確になります。 – Carl
これは価値がありますが、これは 'lens'と' lens-aeson'が非常にきれいに解決するような問題ですが、なぜそれをしばらく避けたいのか分かります。 – Carl