刚性类型变量的麻烦

时间:2017-02-03 17:20:50

标签: haskell

我正在尝试为简单的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值或错误。

readDoublep_date是带String并分别返回Maybe DayMaybe Double的函数。

这里的设计意图是我们使用Comparator令牌告诉我们在内部将输入String更改为什么类型,以便我可以选择是否比较值分别为StringDayDouble

有点像Perl对== vs eq所做的超级基本版本,但是更少的强制和更讨厌的错误消息。

我遇到的问题是,这不会进行类型检查,因为传递给q的谓词最终会显示为Double->Bool而不是a->Bool ,所以我得到一个关于a如何是一个刚性类型变量的错误。

这个错误或多或少对我有意义,但我在想办法解决这个问题时遇到了很多麻烦。

有没有人对如何重组这个有任何建议?

1 个答案:

答案 0 :(得分:4)

开启$equipTest->$description = $description; (例如,将Rank2Types放在文件顶部)并撰写

{-# LANGUAGE Rank2Types #-}