我正在尝试为简单的DSL构建解析器。
我使用以下功能遇到了麻烦:
procP :: ((a->Bool) -> [a] -> Bool) -> String -> Comperator -> ([String] -> Bool)
procP q v c =
case c of
NumE -> q ((==) . unMay . readDouble $ v) . mapMaybe readDouble
NumNE -> q ((/=) . unMay . readDouble $ v) . mapMaybe readDouble
NumLTE -> q ((<=) . unMay . readDouble $ v) . mapMaybe readDouble
NumLT -> q ((<) . unMay . readDouble $ v) . mapMaybe readDouble
NumGTE -> q ((>=) . unMay . readDouble $ v) . mapMaybe readDouble
NumGT -> q ((>) . unMay . readDouble $ v) . mapMaybe readDouble
Exists -> q notBlanks
DatE -> q ((==) . unMay . p_date $ v ) . mapMaybe p_date
DatNE -> q ((/=) . unMay . p_date $ v ) . mapMaybe p_date
DatLTE -> q ((<=) . unMay . p_date $ v ) . mapMaybe p_date
DatLT -> q ((<) . unMay . p_date $ v ) . mapMaybe p_date
DatGTE -> q ((>=) . unMay . p_date $ v ) . mapMaybe p_date
DatGT -> q ((>) . unMay . p_date $ v ) . mapMaybe p_date
TxtE -> q (==v)
TxtME -> (q (==v)) . map (rTrim)
TxtNME -> (q (/=v)) . map (rTrim)
TxtNE -> q (/= v)
此处的细分如下:
q
是一些功能,与前奏中的any
类似。有几种不同的变体,但类型签名应该或多或少相同 - 给定谓词和列表,返回一个bool。
v
是一个字符串输入,用于比较,它有助于构造谓词。
c
是由解析器构造的标记类型,表示我们应该在谓词中使用哪种类型的比较。
unMay
是一个愚蠢的黑客功能,以打开&#34;解开&#34; Just
上的Nothing
值或错误。
readDouble
和p_date
是带String
并分别返回Maybe Day
或Maybe Double
的函数。
这里的设计意图是我们使用Comparator
令牌告诉我们在内部将输入String
更改为什么类型,以便我可以选择是否比较值分别为String
,Day
或Double
。
有点像Perl对==
vs eq
所做的超级基本版本,但是更少的强制和更讨厌的错误消息。
我遇到的问题是,这不会进行类型检查,因为传递给q
的谓词最终会显示为Double->Bool
而不是a->Bool
,所以我得到一个关于a
如何是一个刚性类型变量的错误。
这个错误或多或少对我有意义,但我在想办法解决这个问题时遇到了很多麻烦。
有没有人对如何重组这个有任何建议?
答案 0 :(得分:4)
开启$equipTest->$description = $description;
(例如,将Rank2Types
放在文件顶部)并撰写
{-# LANGUAGE Rank2Types #-}