3

功能:

fn : 'a -> 'b

现在,有没有可以定义并具有这种类型的函数?

4

3 回答 3

5

在标准 ML 中,该函数签名有两种可能的实现。一个使用异常,另一个使用递归:

val raises : 'a -> 'b =
  fn a => raise Fail "some error";

(* Infinite looping; satisfies the type signature, *)
(* but won't ever produce anything.                *)
val rec loops : 'a -> 'b =
  fn a => loops a;

第一个解决方案可能对定义一个辅助函数很有用,比如bug,它可以节省一些击键:

fun bug msg = raise Fail ("BUG: " ^ msg);

另一个解决方案可能对定义服务器循环或 REPL 很有用。

在 Basis 库中,OS.Process.exit有这样一个返回未知泛型类型的函数'a

- OS.Process.exit;
val it = fn : OS.Process.status -> 'a

一个小的 echo REPL 类型val repl = fn : unit -> 'a

fun repl () =
  let
    val line = TextIO.inputLine TextIO.stdIn
  in
    case line of
      NONE        => OS.Process.exit OS.Process.failure
    | SOME ":q\n" => OS.Process.exit OS.Process.success
    | SOME line   => (TextIO.print line ; repl ())
  end

您可能还会发现这个关于 Haskellforever函数的类型签名的问题很有用。

于 2016-01-21T09:17:43.107 回答
2

我能想到一个例子:

fun f a = raise Div;
于 2016-01-20T22:55:08.543 回答
2

我能想到几个:

  1. 一种是递归的,

    fun f x = f x
    
  2. 任何引发异常的函数,

    fun f x = raise SomeExn
    
  3. 任何相互递归的函数,例如,

    fun f x = g x
    and g x = f x
    
  4. 任何使用强制转换的函数(需要特定的编译器支持,以下适用于莫斯科 ML),

    fun f x = Obj.magic x
    

    像这样破坏类型系统可能是作弊,但与所有其他具有这种类型的函数不同,这个函数实际上返回了一些东西。(在最简单的情况下,它是恒等函数。)

  5. 如果 Collat​​z 猜想为假则抛出的函数,如果为真则无限递归,

    fun f x =
        let fun loop (i : IntInf.int) =
                if collatz i
                then loop (i+1)
                else raise Collatz
        in loop 1 end
    

    这实际上只是前两者的组合。

  6. 任何执行任意 I/O 并无限递归的函数,例如

    fun f x = (print "Woohoo!"; f x)
    
    fun repl x =
        let val y = read ()
            val z = eval y
            val _ = print z
        in repl x end
    

有人可能会争辩说异常和无限递归代表相同的理论值⊥(底部),意思是“没有结果”,尽管由于您可以捕获异常而不是无限递归函数,您也可能会争辩它们是不同的。

如果您将自己限制为函数(例如,没有打印或异常)并且只有标准 ML(而不是编译器特定的功能),并且您认为相互递归的情况在功能上是等效的,尽管它们具有不同的递归方案,我们回到只是fun f x = f x

fun f x = f x具有类型'a → 'b的原因可能很明显:类型推断算法假设输入类型和输出类型分别为'a'b并继续得出函数的唯一约束:那f x是输入类型必须等于f x' 的输入类型,并且f x' 的输出类型必须等于f x' 的输出类型,此时类型'a'b还没有被进一步特化。

于 2016-01-21T15:14:20.447 回答