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

没有办法(没有 Template 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 回答