Haskell的新品嚐試編寫解析器。Haskell Typeclasses:我在這裏做錯了什麼?
我已經使用attoparsec成功地將我的輸入文件劃分爲AST中的標記。
我現在想要走AST並從它發出輸出。我認爲我可以通過從類型類派生一些通用例程給Token類,然後在實例中根據Token類型發出代碼時根據需要提供特定函數。
該代碼可能比我的解釋更容易遵循。這是我的嘗試:
class AST a where
children :: a -> [a]
prefix :: a -> String
suffix :: a -> String
node :: a -> [String]
children v = []
prefix v = ""
suffix v = ""
node v = [prefix v] ++ (concatMap node $ children v) ++ [suffix v]
data Token = Line { lnName :: String, lnLines :: Int }
| LineList { llLines :: [Token] }
| Init String
| Main String
| Step { stId :: String, stDuration :: Float }
| Scene { scId :: String, scTokens :: [Token] }
| Sequence { sqId :: String , sqScenes :: [Token] }
| File {flContents :: [Token]} deriving (Show, AST)
所以我的理解是,如果我從類型類派生我已經寫了:
- 我並不需要提供一個實例定義爲所有的該功能具有默認實現
- 我可以根據需要
覆蓋每個令牌類型的默認設置,但是我從GHC一個錯誤,也沒有那麼有用
Parser.hs | 27 col 60 error |不能派生實例
AST Token':
AST'不是衍生類在'令牌'的數據聲明中
不夠公平,但爲什麼會這樣呢?不知道如何解決問題而不知道有什麼信息。任何幫助感激地收到。
我知道這不是一個有用的評論,但我不得不說,絕對愛哈斯克爾。這是一個快樂的學習:)
當心。 Haskell類型類與平均OO語言中的類非常不同。 「派生」只是幫助某些實例變得微不足道(但是討厭,因爲如此廣泛),甚至更容易定義,除此之外別無其他;一般的方式仍然是'實例'。 - 就你而言,我想知道你是否應該使用類型類 - 也許只是另一個「數據」會更好。 – leftaroundabout
順便說一下,在這種情況下使用類型類型絕對沒有優勢。還有哪些其他實例?所有實例遵循哪些規則,以便可以推理有界多態?如果你想在這裏使用多態,可以在'Token'類型上引入一個類型變量,並使用參數多態。 – Carl
嗨,感謝您的評論。我已經將代碼gen實現爲個別類型重載函數。不利的一面是我結束了幾分樣板,我不想和所以我想用默認功能 –