我试图实现一种方法来延迟构造非确定性有限自动机(NFA),我在F#中完成了years ago,现在想在利用Monoid
类型类的同时用Haskell尝试一下。
{-# LANGUAGE TypeSynonymInstances, FlexibleInstances #-}
module NFA where
data State = State Match State | Split State State | Final deriving (Show)
data Match = Any | Char Char | ... deriving (Show)
type StateF = State -> State
complete :: StateF -> State -> State
complete statef exit = statef exit
connect :: StateF -> StateF -> StateF
connect fst snd = complete fst . complete snd
empty :: StateF
empty = id
instance Semigroup StateF where
(<>) = connect
instance Monoid StateF where
mempty = empty
这段代码无法编译,因为我的Semigroup
和Monoid
示例与GHC.Base
中的instance Semigroup b => Semigroup (a -> b)
和instance Monoid b => Monoid (a -> b)
重叠,但我不明白为什么。
我看到函数a -> b
上有一个Monoid
示例,其中b
本身就是Monoid
,但是State
没有Monoid
示例,那么StateF
(State -> State
)怎么会重叠呢?
是因为有人 * 可能 * 在其他地方为State
实现Monoid
吗?
还有,我该怎么解决这个问题?
我知道a可以将StateF
定义为...
data StateF = StateF (State -> State)
......但这也会在模式匹配和构造StateF
时增加语法噪声。
编译器错误:
src\NFA.hs:10:10: error:
* Overlapping instances for Semigroup StateF
arising from a use of `GHC.Base.$dmsconcat'
Matching instances:
instance Semigroup b => Semigroup (a -> b) -- Defined in `GHC.Base'
instance Semigroup StateF -- Defined at src\NFA.hs:10:10
* In the expression: GHC.Base.$dmsconcat @(StateF)
In an equation for `GHC.Base.sconcat':
GHC.Base.sconcat = GHC.Base.$dmsconcat @(StateF)
In the instance declaration for `Semigroup StateF'
|
10 | instance Semigroup StateF where
| ^^^^^^^^^^^^^^^^
src\NFA.hs:10:10: error:
* Overlapping instances for Semigroup StateF
arising from a use of `GHC.Base.$dmstimes'
Matching instances:
instance Semigroup b => Semigroup (a -> b) -- Defined in `GHC.Base'
instance Semigroup StateF -- Defined at src\NFA.hs:10:10
* In the expression: GHC.Base.$dmstimes @(StateF)
In an equation for `GHC.Base.stimes':
GHC.Base.stimes = GHC.Base.$dmstimes @(StateF)
In the instance declaration for `Semigroup StateF'
|
10 | instance Semigroup StateF where
| ^^^^^^^^^^^^^^^^
src\NFA.hs:13:10: error:
* Overlapping instances for Semigroup StateF
arising from the superclasses of an instance declaration
Matching instances:
instance Semigroup b => Semigroup (a -> b) -- Defined in `GHC.Base'
instance Semigroup StateF -- Defined at src\NFA.hs:10:10
* In the instance declaration for `Monoid StateF'
|
13 | instance Monoid StateF where
| ^^^^^^^^^^^^^
src\NFA.hs:13:10: error:
* Overlapping instances for Monoid StateF
arising from a use of `GHC.Base.$dmmappend'
Matching instances:
instance Monoid b => Monoid (a -> b) -- Defined in `GHC.Base'
instance Monoid StateF -- Defined at src\NFA.hs:13:10
* In the expression: GHC.Base.$dmmappend @(StateF)
In an equation for `mappend':
mappend = GHC.Base.$dmmappend @(StateF)
In the instance declaration for `Monoid StateF'
|
13 | instance Monoid StateF where
| ^^^^^^^^^^^^^
src\NFA.hs:13:10: error:
* Overlapping instances for Monoid StateF
arising from a use of `GHC.Base.$dmmconcat'
Matching instances:
instance Monoid b => Monoid (a -> b) -- Defined in `GHC.Base'
instance Monoid StateF -- Defined at src\NFA.hs:13:10
* In the expression: GHC.Base.$dmmconcat @(StateF)
In an equation for `mconcat':
mconcat = GHC.Base.$dmmconcat @(StateF)
In the instance declaration for `Monoid StateF'
|
13 | instance Monoid StateF where
| ^^^^^^^^^^^^^
1条答案
按热度按时间jhdbpxl91#
至少对于所示的代码,将
StateF
从类型别名更改为newtype
只会带来最小的更改,并且没有运行时开销。如果使用记录语法,则
complete
甚至不需要模式匹配:(Don(不要把
complete
看作实际上把状态转换器 * 应用 * 到一个状态,而是 * 提取 * 状态转换器,以便它 * 可以 * 应用到一个状态。)