內部分配功能給一個變量我試圖創建數值的秒差距解析器。這些值可以是Integer
或Double
。它們也可以是有符號或無符號的。我創建了一個符號解析器,它爲+
和negate
返回-
的多態函數id
。當我給出多態符號函數和Either Integer Double
時,我也有一個函數構造我的表達式節點的正確版本。我試圖把它放在一起,如下面簡化版本的代碼所示。
{-# LANGUAGE RankNTypes #-}
-- (...)
data Expr = IntExpr Integer | DoubleExpr Double
pSign :: Num a => MyParser (a -> a) -- returns id for + or negate for -
pReal :: (forall a. Num a => a -> a) -> Either Integer Double -> MyParser Expr
pNum :: MyParser Expr
pNum = do
sign <- pSign
numVal <- ParsecToken.naturalOrFloat lexer
pReal sign numVal
當我使用上面的代碼時,出現編譯錯誤「Could not deduce(a〜Integer)...」。
當我定義我的單子一個let
語句內簽到功能改變我的代碼,一切編譯罰款:
pNum :: MyParser Expr
pNum = do
sign <- pSign
numVal <- ParsecToken.naturalOrFloat lexer
let t = sign 1
sign' :: Num a => a -> a
sign' = if t == 1 then id else negate
pReal sign numVal
我的猜測是,在第一種情況下,polymophic型sign
被莫名其妙地丟失,轉換到Integer -> Integer
。
問題
- 什麼機制使原來
sign :: Num a => a -> a
單子變量不爲pReal :: (forall a. Num a => a -> a) -> ...
第一個參數工作,而其重新定義了同類型的版本(sign'
)的作品? - 如何在我的monad中實現將在我的monad中創建的多態變量
sign
傳遞給pReal
函數,而無需重新定義它(sign'
)?
注意
我已經嘗試過的方法一樣的sign
明確定義類型與
pNum = pSign >>= \(sign :: Num a => a -> a) -> do ...
或具有正常功能的定義相同等
請注意,我知道,我可以簡化代碼,只需返回一個來自sign
的布爾變量而不是多態函數灰。這個問題的關鍵在於瞭解類型如何在這裏工作。
在未來,這是禮貌,包括一個完整的,可編譯例子 - 打樁了一些無關緊要的事情,包括必要的進口,等等'undefined'或類似的是好的,只是,只要我能放棄它在我的文本編輯器,並立即開始玩它。 –
@DanielWagner:謝謝你的提示。我並沒有通過'undefined'來描述,所以我包含了沒有定義的不可編譯的版本。 – Xilexio