こんにちは私は、エラーメッセージ*** 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
答えて
read
はタイプread :: Read a => String -> a
を持つ関数である:
は、ここに私のコードです。これはread
がString
を入力として受け取り、a
がRead
タイプのクラスを実装していれば、あるタイプの値a
を返します。 read
は返す特定の型を知っていなければならず、型が明示的に与えられているか(例えばread "123" :: Int
またはread "True" :: Bool
)、それはコンテキストから推論されます。あなたのケースでは、read
はInt
を返す必要があると推定しています。はInt
を2番目のパラメータと想定しているからです。この場合、式read [y]
は、Char
をy
とし、それを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])
入力メッセージの形式は問題です。行を文字列として読み込み、文字列内の文字を照合しています(文字列は[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
)を容易に抽出することができますこの方法です。