我想用Haskell写一个基本的词法分析器。为了实现DFA和NFA,我决定将一些常用函数放入FA和FAS类。多参数类没有实例错误
-- |A class for defining the common functionality of all finite automatons.
class FA a b where
mutateId :: a -> Int -> a -- ^Returns a new FA by changing the sId of the input FA.
mutateType :: a -> StateType -> a -- ^Returns a new FA by changing the stateType of the input FA.
addTransition :: a -> (b, a) -> a -- ^Returns a new FA by adding a new transition to the input FA.
-- |A class for defining the common functionality of all finite automaton states.
class FA a b => FAState a b where
sId :: a -> Int -- ^An unique identifier for the state(hence the prefix s).
sType :: a -> StateType -- ^The type of the state.
sTransitions :: a -> Transitions b a -- ^The transitions that occur from this state.
其中,
-- |A type which identifies different types of a FA state.
data StateType = Start | Normal | Final
deriving (Show, Read, Eq)
-- |A type which represents a list of transitions on input a to b.
-- Eg. [(Char, DFA)] represents the transition on a Char input.
type Transitions a b = [(a, b)]
因此,b表示为发生转变的数据类型。对于DFA,b = Char,而对于NFA,b =符号。
data Symbol = Alphabet Char | Epsilon
deriving (Show, Read, Eq)
DFA和NFA分别定义为:
data DFA = DState Int StateType (Transitions Char DFA)
deriving (Show, Read)
data NFA = NState Int StateType (Transitions Symbol NFA)
deriving (Show, Read)
我在与FA & FAState的实例定义一个问题:
instance FA DFA Char where
mutateId (DState i ty ts) new_i = DState new_i ty ts
mutateType (DState i ty ts) new_ty = DState i new_ty ts
addTransition (DState i ty ts) state = DState i ty (state:ts)
instance FAState DFA Char where
sId (DState i t ts) = i
sType (DState i t ts) = t
sTransitions (DState i t ts) = ts
instance FA NFA Symbol where
mutateId (NState i ty ts) new_i = NState new_i ty ts
mutateType (NState i ty ts) new_ty = NState i new_ty ts
addTransition (NState i ty ts) state = NState i ty (state:ts)
instance FAState NFA Symbol where
sId (NState i t ts) = i
sType (NState i t ts) = t
sTransitions (NState i t ts) = ts
在试图运行任何功能我得到一个没有实例的错误:
>>sId egNFA
<interactive>:15:1:
No instance for (FAState NFA b0)
arising from a use of `sId'
Possible fix: add an instance declaration for (FAState NFA b0)
In the expression: sId egNFA
In an equation for `it': it = sId egNFA
我不明白这里发生了什么。
还有一个老的延迟统一技巧,你假装一个类型参数是非常通用的,然后扭曲GHC的手臂,使其具体化为一个实例,但这对于参与声誉不佳的诡计是非常有用的。 –
@ C.A.McCann啊,是的,很好的建议。我会添加它。 –
在发布这个问题之前,我对函数依赖关系做了一些阅读,但我不认为它适用于这种情况,因为我无法理解编译器如何通过a推导出b的值。我的意思是怎么说“b可以用a找出来”,帮助编译器找到b? – Likhit