我正在努力研究Haskell,方法是尝试写一些我觉得很有趣的东西,现在我正试图找出如何在Haskell中派生Semiring来解决一组特定的解析问题:
class Semiring s where
zero, one :: s
mul, add :: s -> s -> s
instance Semiring Bool where
zero = False
one = True
add = (||)
mul = (&&)
instance Semiring (Set String) where
zero = empty
one = singleton ""
add a b = union a b
mul a b = Data.Set.map (\(c, d) -> c ++ d) $ cartesianProduct a b
布尔({true,false},∨,∧,false,true)版本效果很好。Int版本也是如此。最后一个称为解析森林,其表示形式为(E,∪,·,∅,{<>}),其中E是一组字符串,而{<>}是空字符串的集合。
当我尝试对此进行编译时,我得到:
Rigge… 115 10 error • Illegal instance declaration for ‘Semiring (Set String)’
(All instance types must be of the form (T a1 ... an)
where a1 ... an are *distinct type variables*,
and each type variable appears at most once in the instance head.
这对我来说没有太大意义。Set String
是一个独特的类型,对,并且的所有操作class Semiring
应仅根据字符串集来表示。
如果需要上下文,则该项目位于Rigged Regular Expressions处。Bool版本仅报告正则表达式匹配;一个Int版本会报告正则表达式可以匹配的不同方式的数量("a" ~ /(a|a*)/
即将返回,2
因为两个不同且唯一的子表达式匹配);ParseForest不应返回方法的数量,而应返回所有可能方法的集合,但是它不能返回,因为我不明白为什么我不能使用具体的数据类型Set String
,其中另一个具体的数据类型像Int
或Bool
工作好的。
关键部分是
of the form (T a1 ... an) where a1 ... an are *distinct type variables*,
您的类型是Set String
,所以T = Set
and a1 = String
(和n=1
)。但是String
是类型,而不是类型变量。合规实例将改为
instance (....) => Semiring (Set a) where
...
无论如何,这是Haskell2010的古老限制,您可以忽略。在现代GHC Haskell中,您可以打开FlexibleInstances
扩展名,并使用自己的实例而不会出现问题。GHC本身应建议在错误消息中将其打开。
请注意,如今几乎没有人在严格的Haskell2010中编程:有太多的扩展已变得太常用了。可以说,应该对报告进行修订,例如Haskell2020,其中包含了大多数常见的无害扩展,以造福于大国。不过,直到有人真正做到这一点,我们将需要经常打开扩展。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句