Exception 是否可以在StringCvt.scanInt函数中使用精确的流位置信息引发异常?

Exception 是否可以在StringCvt.scanInt函数中使用精确的流位置信息引发异常?,exception,exception-handling,sml,ml,Exception,Exception Handling,Sml,Ml,StringCvt中的解析函数如果发现任何错误,可能会引发异常,问题是引发的异常不包含任何精确的位置信息,因此其调用方无法知道问题的确切原因。在我的第一个想法中,一个直接的解决方案是引发一个包含问题流的异常,例如,更改 if W32.<(largestPosInt32, word) then raise Overflow else SOME(fromWord32 word, rest) 声明带有抽象类型值的异常没有任何障碍,因此我不确定是否理解您的问题。异常将在抽象类型的签名中声明,并带

StringCvt中的解析函数如果发现任何错误,可能会引发异常,问题是引发的异常不包含任何精确的位置信息,因此其调用方无法知道问题的确切原因。在我的第一个想法中,一个直接的解决方案是引发一个包含问题流的异常,例如,更改

if W32.<(largestPosInt32, word)
then raise Overflow
else SOME(fromWord32 word, rest)

声明带有抽象类型值的异常没有任何障碍,因此我不确定是否理解您的问题。异常将在抽象类型的签名中声明,并带有该类型的关联值。

声明带有抽象类型值的异常没有任何障碍,因此我不确定是否理解您的问题。异常将在抽象类型的签名中声明,并具有该类型的关联值。

您可以在本地定义引用多态类型变量的异常,并且可以在本地引发和捕获它们。例如:

fun 'a f(x : 'a) =
    let
      exception E of 'a
      fun g() = raise E x
      fun h() = g() handle E y => y
    in
      h()
    end
exception E of 'a  (* hypothetical existential exception *)
fun f1() = raise E 1
fun f2() = raise E "foo"
fun g f = f() handle E x => ()  (* type of x is abstract here *)
请注意,这不是多态性异常——它相对于范围中的类型
'a
是单态的,您只能将其应用于该类型的值,即仅
x

因此,无法全局定义此类异常,因为全局范围中不存在类型变量(应该在哪里绑定或实例化它们?)

在SML中不能有真正的多态异常。原则上,允许通过存在量化实现这一点是可能的,但在实践中并不十分有用。由于在匹配异常时无法知道该类型,因此必须将该类型视为完全抽象的类型。例如:

fun 'a f(x : 'a) =
    let
      exception E of 'a
      fun g() = raise E x
      fun h() = g() handle E y => y
    in
      h()
    end
exception E of 'a  (* hypothetical existential exception *)
fun f1() = raise E 1
fun f2() = raise E "foo"
fun g f = f() handle E x => ()  (* type of x is abstract here *)
唯一稍微有用的例子是

exception E of ('a -> int) * 'a
fun f1() = raise E(fn x => x, 1)
fun f2() = raise E(String.size, "foo")
fun g f = f() handle E(h, x) => h x
但没有什么理由不用不需要存在类型的更简单版本来取代它:

exception E of unit -> int
fun f1() = raise E(fn() => 1)
fun f2() = raise E(fn() => String.size "foo")
fun g f = f() handle E h => h()

实际上,可能没有人希望在异常中传递一级ADT…

您可以在本地定义引用多态类型变量的异常,并且可以在本地引发和捕获它们。例如:

fun 'a f(x : 'a) =
    let
      exception E of 'a
      fun g() = raise E x
      fun h() = g() handle E y => y
    in
      h()
    end
exception E of 'a  (* hypothetical existential exception *)
fun f1() = raise E 1
fun f2() = raise E "foo"
fun g f = f() handle E x => ()  (* type of x is abstract here *)
请注意,这不是多态性异常——它相对于范围中的类型
'a
是单态的,您只能将其应用于该类型的值,即仅
x

因此,无法全局定义此类异常,因为全局范围中不存在类型变量(应该在哪里绑定或实例化它们?)

在SML中不能有真正的多态异常。原则上,允许通过存在量化实现这一点是可能的,但在实践中并不十分有用。由于在匹配异常时无法知道该类型,因此必须将该类型视为完全抽象的类型。例如:

fun 'a f(x : 'a) =
    let
      exception E of 'a
      fun g() = raise E x
      fun h() = g() handle E y => y
    in
      h()
    end
exception E of 'a  (* hypothetical existential exception *)
fun f1() = raise E 1
fun f2() = raise E "foo"
fun g f = f() handle E x => ()  (* type of x is abstract here *)
唯一稍微有用的例子是

exception E of ('a -> int) * 'a
fun f1() = raise E(fn x => x, 1)
fun f2() = raise E(String.size, "foo")
fun g f = f() handle E(h, x) => h x
但没有什么理由不用不需要存在类型的更简单版本来取代它:

exception E of unit -> int
fun f1() = raise E(fn() => 1)
fun f2() = raise E(fn() => String.size "foo")
fun g f = f() handle E h => h()

在实践中,可能没有人希望在例外情况下传递一流的ADT…

对不起,我使用了一个错误的术语。简而言之,我想引发一个包含类型变量的异常。例如,在类型为“a*”b->”c的函数中引发包含“b”的异常。问题已更新。非常感谢。对不起,我用错词了。简而言之,我想引发一个包含类型变量的异常。例如,在类型为“a*”b->”c的函数中引发包含“b”的异常。问题已更新。非常感谢。问题是:你会如何处理这些信息?如果异常真的可以携带任何类型(例如,存在量化),那么在捕获异常的地方,您将无法知道有效负载的实际类型,因此您无法将其用于任何事情。它不是任何类型,而是受关闭函数约束的类型变量,即,在函数
'a*'b->'b
中引发类型为
的异常,异常为'b
。写出来后,我想我知道问题所在。为了让其他人处理异常,应该在顶层声明异常,在顶层没有绑定类型变量,那么就不可能使异常具有多态性。谢谢你的评论,我想我理解这个问题。问题是:你会如何处理这些信息?如果异常真的可以携带任何类型(例如,存在量化),那么在捕获异常的地方,您将无法知道有效负载的实际类型,因此您无法将其用于任何事情。它不是任何类型,而是受关闭函数约束的类型变量,即,在函数
'a*'b->'b
中引发类型为
的异常,异常为'b
。写出来后,我想我知道问题所在。为了让其他人处理异常,应该在顶层声明异常,在顶层没有绑定类型变量,那么就不可能使异常具有多态性。谢谢你的评论,我想我理解这个问题。