2013-05-25 45 views
1

例如;如何從Haskell中的String讀取遞歸數據結構?

data TRAINING=AGAIN Int [TRAINING] 
       |RUN 
       |JUMP 
       |PUNCH Int 
      deriving (Eq,Show,Read) 

定義,我想的是,如果用戶輸入類似:

"RUN, PUNCH 15, AGAIN 3 [JUMP, AGAIN 2 [PUNCH 20]]" 

那麼程序應該返回

[RUN,PUNCH 15,AGAIN 3 [JUMP,AGAIN 2 [PUNCH 20]]] 

所以我寫了

fight :: String->[TRAINING] 
    fight xs=[read xs ::TRAINING] 

但我得到了「沒有解析Exc主器件接收」。我是新手,我想知道什麼是「無解析異常」,我該如何解決它?

回答

6

一個沒有解析異常意味着你給了Haskell不是Read實例的正確模式。在這種情況下,這是因爲列表如下所示:

[<show element>,<show element>...] 

而你錯過了外括號。解決這個問題就像看看輸出應該是什麼一樣簡單:

Prelude> show [RUN,PUNCH 15,AGAIN 3 [JUMP,AGAIN 2 [PUNCH 20]]] 
     "[RUN,PUNCH 15,AGAIN 3 [JUMP,AGAIN 2 [PUNCH 20]]]" 

所以你需要用[]來包圍整個事物。你的功能是正確的,你只是有一個稍微不正確的輸入字符串。

如果你不喜歡這個限制,那麼可能是編寫Parsec或類似的簡單解析器的時候了。如果你對Haskell完全陌生,這可能會有點困難。

+0

空間不會傷人,'read'可以處理那些罰款。 –

+0

真的嗎?謝謝編輯 – jozefg

+0

儘管我喜歡Parsec,但爲此只需手工編寫遞歸下降解析器就沒有什麼挑戰性,只是稍微乏味。 – Wes

1

換句話說,以下jozefg的回答是:

fight xs = read xs ::[TRAINING] 

也:周圍的逗號

"[RUN, PUNCH 15, AGAIN 3 [JUMP, AGAIN 2 [PUNCH 20]]]" 
+0

,但這並不實際修復 – nbdip

+0

@nbdip這很有趣...設置'鬥爭XS =閱讀xs :: [TRAINING]'並輸入'fight'[RUN,PUNCH 15,AGAIN 3 [JUMP,AGAIN 2 [PUNCH 20]]]''是使用你的數據結構的唯一方法。你怎麼修好它的? –