2016-09-10 9 views
0

こんにちは私は、エラーメッセージ*** Exception: Prelude.read: no parseを私の機能の1つに載せて、CIS194 Spring 13を完了しようとしています。関数のファイルはLogAnalysis.hsで、関数はparseMessageですが、ファイルはLog.hsからインポートされます。なぜこのエラーメッセージが表示され、どうすれば修正できますか? https://github.com/Adam-Morris/CIS194/tree/master/Homework-2Haskell *** Exception:Prelude.read:no parse

答えて

1

readはタイプread :: Read a => String -> aを持つ関数である:

は、ここに私のコードです。これはreadStringを入力として受け取り、aReadタイプのクラスを実装していれば、あるタイプの値aを返します。 readは返す特定の型を知っていなければならず、型が明示的に与えられているか(例えばread "123" :: Intまたはread "True" :: Bool)、それはコンテキストから推論されます。あなたのケースでは、readIntを返す必要があると推定しています。はIntを2番目のパラメータと想定しているからです。この場合、式read [y]は、Charyとし、それを1要素の文字列に変換し、それを解析してIntに変換しようとします。今度はyに10進数でない文字が含まれていると、それを整数に変換する方法がわからないため、例外がスローされて失敗します。

どうすればこの問題に対処できますか?呼び出す前にreadへの入力がOKであることを確認する必要があります。たとえば、あなたがyは(appropriate functionを使用して)数字であることを確認することができます。また

parseMessage (x:y:z) 
    | x == 'I' && isDigit y = LogMessage Info (read [y]) (unwords [z]) 
    ... 

、あなたはreadのようなものであることText.ReadからreadMaybeを使用することができますが、それが失敗した場合、それは返す代わりに、例外をスローしません無価値:

parseMessage (x:y:z) 
    | x == 'I', Just n <- readMaybe [y] = LogMessage Info n (unwords [z]) 
0

入力メッセージの形式は問題です。行を文字列として読み込み、文字列内の文字を照合しています(文字列は[Char]の型名です)。あなたのsample.log最初の行(I 6 Completed armadillo processing)で はparseMessageに文字列として渡されることになる、とのパラメータは次の値をとります:

x = 'I'

y = ' ' --single white space character

z = "6 Completed armadillo processing"

readは空白文字を取得して投げる*** Exception: Prelude.read: no parse

値を得るためには、次の操作を行うことができます:

parseMessage :: String -> LogMessage 
    parseMessage msg = 
     case words msg of 
     "I":y:z -> LogMessage Info (read y :: TimeStamp) (unwords z) 
     "W":y:z -> undefined 
     "E":y:z -> undefined 
     _  -> undefined 

最初の2つの有効なワード(MessageTypeこの場合のTimeStamp)を容易に抽出することができますこの方法です。