我在编写解析器时遇到了问题。具体来说,我想成为不同类型的返回值。例如,我有两种不同的数据类型FA
并PA
代表两种不同的脂质类 -
data FA = ClassLevelFA IntegerMass
| FA CarbonChain
deriving (Show, Eq, Ord)
data PA = ClassLevelPA IntegerMass
| CombinedRadylsPA TwoCombinedRadyls
| UnknownSnPA Radyl Radyl
| KnownSnPA Radyl Radyl
deriving (Show, Eq, Ord)
使用 attoparsec,我构建了解析器来解析脂质速记符号。对于上面的数据类型,我有解析器faParser
和paParser
. 我希望能够解析 anFA
或PA
. 但是,由于FA
和PA
是不同的数据类型,我不能执行以下操作 -
inputParser = faParser
<|> paParser
我最近了解了 GADT,我认为这可以解决我的问题。因此,我制作了一个 GADT 和一个eval
函数,并更改了解析器faParser
和paParser
. -
data ParsedLipid a where
ParsedFA :: FA -> ParsedLipid FA
ParsedPA :: PA -> ParsedLipid PA
eval :: ParsedLipid a -> a
eval (ParsedFA val) = val
eval (ParsedPA val) = val
这让我很接近,但它看起来好像ParsedFA
并且ParsedPA
是不同的数据类型?例如,解析"PA 17:1_18:1"
给了我一个类型的值ParsedLipid PA
(不只是ParsedLipid
我所期望的)。因此,解析器inputParser
仍然不进行类型检查。
let lipid = use "PA 17:1_18:1"
*Main> :t lipid
lipid :: ParsedLipid PA
关于如何解决这个问题的任何建议?