如何匹配这种类型

时间:2017-12-05 10:58:40

标签: haskell

我有:

infixr 9 |||
data a ||| b = A a|B b deriving (Eq, Data, Show)

class IsTag a where
  anyTag :: a

并且我保留了a|||b这些IsTag的实例值,例如:A (B (A x)) - 嵌套的深度可以是任何肯定的。我想编写一个函数来检测x等于anyTag,所以它需要a|||b并返回Bool - 是基础值(x例子)等于x实例的anyTag。怎么写这样的功能?由于“无限类型”等错误,我无法进行模式匹配。我将deriving Data添加到a|||b和x的类型,希望可以使用{{{{{ 1}},但我无法理解如何通过这种递归类型进行折叠/遍历。

1 个答案:

答案 0 :(得分:2)

它不会比这更好:

{-# LANGUAGE DefaultSignatures #-}
class IsAnyTag a where
    isAnyTag :: a -> Bool
    default isAnyTag :: (Eq a, IsTag a) => a -> Bool
    isAnyTag = (anyTag ==)

instance (IsAnyTag a, IsAnyTag b) => IsAnyTag (a ||| b) where
    isAnyTag (A a) = isAnyTag a
    isAnyTag (B b) = isAnyTag b

-- and one more line of `instance IsAnyTag X` for each `X` that
-- is an instance of `IsTag`

这里的主要缺点是,即使您只测试一方,这也要求|||两侧的类型必须是IsAnyTag个实例。他们是静态类型检查的中断。

相关问题