2017-02-03 11 views
1

私は単純な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は、述部でどのタイプの比較を使用するかを表すパーサーによって構築されたトークンタイプです。

Nothingの値またはエラーJustを「アンラップする」ための愚かなハック機能です。

readDoublep_dateStringを取り、それぞれ、Maybe DayまたはMaybe Doubleのいずれかを返す関数です。

ここで設計意図は、我々は、私がStringとして値と比較するかどうかを選択することができるように、内部に入力String秒を変更するにはどのようなタイプを教えするComparatorトークンを使用していることである、Day、またはそれぞれDoubleである。

Perlが行うのは、== vs eqというスーパーベーシックバージョンのようなものですが、強制的なエラーメッセージはほとんどありません。

私がいる問題はqに渡されたばかり述語がタイプDouble->Boolの代わりa->Boolとして提示終わるので、これは、型チェックしないことです、と私はaは剛性型変数である方法に関するエラーが出ます。

エラーは多少なりとも私には意味がありますが、私は問題を回避する方法を考えています。

誰にもこれを再構成する方法に関するアドバイスはありますか? Rank2Types

+0

可能な複製を書く:GHCが型を推論することはできません。型シグネチャエラーによってバインドされた厳格な型の変数](http://stackoverflow.com/questions/22778098/haskell-ghc-cannot-deduce-type-rigid-type-variable-bound-by-the-type-signature) – jberryman

+1

'TxtME'と' TxtNME'の 'rTrim'dでなければなりませんか? – Gurkenglas

+0

@Gurkenglas - ニースキャッチ。ありがとう! –

答えて

4

電源を入れます(例えば、ファイルの先頭に{-# LANGUAGE Rank2Types #-}を置くことによって)とHaskellの[の

--   vvvvvvvvv difference is here 
procP :: (forall a. (a->Bool) -> [a] -> Bool) -> String -> Comperator -> ([String] -> Bool) 
+0

ありがとう!これは完璧に機能し、私が恐れていたよりはるかに少ない仕事でした。 –