在StringCvt中解析函數可能會引發異常,如果他們發現任何錯誤,問題是引發的異常不包含任何精確的位置信息,因此它的調用者無法知道究竟在哪裏導致問題。我首先想到的一個直接的解決方案是提高包含問題流異常,例如,改變是否有可能在StringCvt.scanInt函數中引發精確的流位置信息異常?
if W32.<(largestPosInt32, word)
then raise Overflow
else SOME(fromWord32 word, rest)
到
if W32.<(largestPosInt32, word)
then raise (Overflow rest)
else SOME(fromWord32 word, rest)
異常Overflow
將承擔額外rest
。但rest
屬於多態類型,換句話說,假設函數的類型爲(char, 'a) StringCvt.reader -> (int, 'a) StringCvt.reader
,我想在此函數中引發異常exception ParseError of string * 'a
,但我不知道如何在Standard ML中執行此操作。 請問有什麼其他解決方法?提前致謝。
再次更新。 我現在用一個仿函數來解決這個問題,但它不如一個簡單的函數那麼方便。骨架代碼,
functor Foo(structure arg : sig
type opaque
type stream
val refopaque : stream -> opaque
end) :
sig
type opaque
type stream
exception SomeError of string * opaque
end =
struct
type opaque = arg.opaque
type stream = arg.stream
val refopaque = arg.refopaque
exception SomeError of string * opaque
fun parse getc cs
... raise SomeError("error", refopaque cs)
...
end
問題是:你會如何處理這些信息?如果異常真的可以攜帶_any_類型(例如,存在量化),那麼在你發現異常的地方,你無法知道實際有效負載的類型,所以你不能用它來做任何事情。 –
它不是_any_類型,而是一個由關閉函數綁定的類型變量,即在函數a *'b - >'b'中引發'b'異常類型的異常。寫完後,我想我知道這個問題。爲了讓其他人處理這個異常,應該在頂層聲明異常,並且不綁定任何類型變量,那麼就不可能使異常變爲多態。感謝您的評論,我想我明白了這個問題。 – MingyanGuo