我不知道如果有人有一个好名字就这么说,请告诉我。
我正在尝试编写一个名为Matchable
的类型类。这个想法是我有几种不同类型的正则表达式(RegExp a
,ComplexRegex 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 Char
和String
。有没有办法做到这一点?感谢。
答案 0 :(得分:6)
保持简单,为什么不让Matchable
的类变量有类* -> *
? (有关更高级别课程的其他示例,请参阅Functor
,Applicative
,Monad
,Foldable
,Traversable
。
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 Char
与RegExp Char
进行匹配。
答案 1 :(得分:2)
作为Alec解决方案的替代方案,您可以使用associated types。这允许没有种类* -> *
的类型,但如果没有必要,我会选择更简单的解决方案。例如。想象一下,RegExp a
和ComplexRegex 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)
您可能正在寻找更高级的类型。如果您只对Char
和String
感兴趣,并且函数的行为仅取决于它是RegExp
还是ComplexRegex
,那么您可以定义下一个类型类:
class Matchable r where
-- regex, input, success
match :: r Char -> String -> Bool
此处r
是类型变量,其类型为* -> *
。简单来说,它是不完整类型。像Maybe
一样。您的函数无法使用Maybe -> Int
类型,因为Maybe
类型不完整,但Maybe Bool
是完整类型。与正则表达式类似:RegExp
和ComplexRegex
都是不完整的类型。感谢Haskell到达类型系统,您的函数也可以在不完整类型上进行参数化。所以稍后在定义实例时,您将以下一种方式编写它们:
instance Matchable RegExp where
... -- implementation for RegExp goes here
instance Matchable ComplexRegex where
... -- implementation for CompltexRegex goes here
在明确指定类型的函数和类型类型时,您可以找到有助于-XKindSignatures
和-XInstanceSigs
语言扩展。