1

任意の型をリストに変換しようとするジェネリック関数を実装したいと思います。私は:の助けを借りてこれを達成しようとしましたTypeable

import Data.Data
import Data.Foldable
import Control.Applicative

asFoldable :: (Typeable (a b), Foldable z, Typeable (z b)) => a b -> Maybe (z b)
asFoldable = cast

asList :: (Typeable1 a, Typeable b) => a b -> Maybe [b]
asList x = Data.Foldable.foldr (:) [] <$> asFoldable x

上記のコードは、asList定義がなくても問題なくコンパイルされますが、それを使用すると、t0型変数のあいまいさを吠え続けaます。今、私はそれをだまそうとしましたが、Maybe [String]orMaybe (Set String)などのキャストに特定のタイプを指定した場合にのみ機能します。

私の推測では、asFoldable型宣言でコンパイラーをだますことができましたが、型クラスへのキャストをサポートしていないため、それでも機能しません。これは本当ですか?任意のタイプをリストに変換しようとするより良い方法はありますか?何かありますか?

4

1 に答える 1

5

型クラスのインスタンスの存在を動的にテストする方法はありません(テンプレートHaskellがなければ、ほとんどの場合、やり過ぎです)。一般的な方法で任意の構造を他の任意の構造に変換する正しい方法は、を使用することData.Dataです。これは、@hammarが他の質問で話していた一般的なものです。

toTree :: Data a => a -> Tree String
toTree x = Node (show $ toConstr x) $ gmapQ toTree x

もちろん、@ hammarも言ったように、リストと文字列を別の方法で処理したい場合があります。

于 2012-11-19T21:07:49.283 に答える