ml function of type fn : 'a -> 'b

生来就可爱ヽ(ⅴ<●) 提交于 2019-12-10 18:19:32

问题


The function:

fn : 'a -> 'b

Now, are there any functions which can be defined and have this type?


回答1:


There are two possible implementations for that function signature in Standard ML. One employs exceptions, the other recursion:

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;

The first solution may be useful for defining a helper function, say bug, which saves a few key strokes:

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

The other solution may be useful for defining server loops or REPLs.

In the Basis library, OS.Process.exit is such a function that returns an unknown generic type 'a:

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

A small echo REPL with type 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

You might also find useful this question about the type signature of Haskell's forever function.




回答2:


I can think of one example:

fun f a = raise Div;



回答3:


I can think of several:

  1. One that is recursive,

    fun f x = f x
    
  2. Any function that raises exceptions,

    fun f x = raise SomeExn
    
  3. Any function that is mutually recursive, e.g.,

    fun f x = g x
    and g x = f x
    
  4. Any function that uses casting (requires specific compiler support, below is for Moscow ML),

    fun f x = Obj.magic x
    

    Breaking the type system like this is probably cheating, but unlike all the other functions with this type, this function actually returns something. (In the simplest case, it's the identity function.)

  5. A function that throws if the Collatz conjecture is false, recurses infinitely if true,

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

    which is really just a combination of the first two.

  6. Any function that performs arbitrary I/O and recurses infinitely, e.g.

    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
    

One may argue that exceptions and infinite recursion represent the same theoretical value ⊥ (bottom) meaning "no result", although since you can catch exceptions and not infinitely recursive functions, you may also argue they're different.

If you restrict yourself to pure functions (e.g. no printing or exceptions) and only Standard ML (and not compiler-specific features) and you think of the mutually recursive cases as functionally equivalent in spite of their different recursion schemes, we're back to just fun f x = f x.

The reason why fun f x = f x has type 'a → 'b is perhaps obvious: The type-inference algorithm assumes that the input type and the output type are 'a and 'b respectively and goes on to conclude the function's only constraint: That f x's input type must be equal to f x's input type, and that f x's output type must be equal to f x's output type, at which point the types 'a and 'b have not been specialized any further.



来源:https://stackoverflow.com/questions/34912121/ml-function-of-type-fn-a-b

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!