匹配Haskell类型类中的类型

时间:2017-06-02 21:16:22

标签: haskell typeclass

我不知道如果有人有一个好名字就这么说,请告诉我。

我正在尝试编写一个名为Matchable的类型类。这个想法是我有几种不同类型的正则表达式(RegExp aComplexRegex a)应该能够匹配输入。

所以我尝试了这个:

class Matchable a where
  --   regex, input, success
  match :: a -> b -> Bool

但我真正想要的是使用类型构造函数变量解构类型类中的构造函数:

class Matchable a where
  --   regex, input, success
  match :: (B a) -> [a] -> Bool

这样我就可以在RegExp Char上匹配ComplexRegex CharString。有没有办法做到这一点?感谢。

3 个答案:

答案 0 :(得分:6)

保持简单,为什么不让Matchable的类变量有类* -> *? (有关更高级别课程的其他示例,请参阅FunctorApplicativeMonadFoldableTraversable

class Matchable b where
  --   regex, input, success
  match :: b a -> [a] -> Bool

instance Matchable ComplexRegex where
  -- match :: ComplexRegex a -> [a] -> Bool
  match = error "unimplemented"

instance Matchable RegExp where
  -- match :: RegExp a -> [a] -> Bool
  match = error "unimplemented"

然后,您可以使用String ~ [Char]ComplexRegex CharRegExp Char进行匹配。

答案 1 :(得分:2)

作为Alec解决方案的替代方案,您可以使用associated types。这允许没有种类* -> *的类型,但如果没有必要,我会选择更简单的解决方案。例如。想象一下,RegExp aComplexRegex a除了StringRegex之外没有参数化,或者你只能为match实现ComplexRegex Char而不是{{1} }}:

ComplexRegex a

另一个不同之处在于,您的实例可以确保class Matchable b where type Target b :: * -- regex, input, success match :: b -> [Target b] -> Bool instance Eq a => Matchable (ComplexRegex a) where type Target (ComplexRegex a) = a -- match :: ComplexRegex a -> [a] -> Bool match = error "unimplemented" instance Matchable StringRegex where type Target StringRegex = Char -- match :: StringRegex -> [Char] -> Bool match = error "unimplemented" -- requires FlexibleInstances instance Matchable (ComplexRegex Char) where type Target (ComplexRegex Char) = Char -- match :: ComplexRegex Char -> [Char] -> Bool match = error "unimplemented" ,而不是将其设置为Eq (Target b)的类型(您也可以将其作为要求:match)。

答案 2 :(得分:1)

您可能正在寻找更高级的类型。如果您只对CharString感兴趣,并且函数的行为仅取决于它是RegExp还是ComplexRegex,那么您可以定义下一个类型类:

class Matchable r where
  --   regex, input, success
  match :: r Char -> String -> Bool

此处r是类型变量,其类型为* -> *。简单来说,它是不完整类型。像Maybe一样。您的函数无法使用Maybe -> Int类型,因为Maybe类型不完整,但Maybe Bool是完整类型。与正则表达式类似:RegExpComplexRegex都是不完整的类型。感谢Haskell到达类型系统,您的函数也可以在不完整类型上进行参数化。所以稍后在定义实例时,您将以下一种方式编写它们:

instance Matchable RegExp where
   ... -- implementation for RegExp goes here

instance Matchable ComplexRegex where
   ... -- implementation for CompltexRegex goes here

在明确指定类型的函数和类型类型时,您可以找到有助于-XKindSignatures-XInstanceSigs语言扩展。