Standard ML Syntax

2019-07-20 16:56发布

问题:

I'm new to Standard ML and trying to write the following code

 fun whilestat test stmt1  = 
        (fn x => if (test x) then (stmt1 x;whilestat test stmt1 ) else (x) );

The issue is that it gives me the following error

w.sml:21.6-22.82 Error: right-hand-side of clause doesn't agree with function result type [circularity]
expression:  ('Z -> 'Y) -> 'Z -> 'Z
result type:  ('Z -> 'Y) -> 'Z
in declaration:
whilestat2 = (fn arg => (fn <pat> => <exp>))

uncaught exception Error
 raised at: ../compiler/TopLevel/interact/evalloop.sml:66.19-66.27
         ../compiler/TopLevel/interact/evalloop.sml:44.55
         ../compiler/TopLevel/interact/evalloop.sml:292.17-292.20

Im just trying to emaulate a while condition where if the staement is true then it recurses, else returns the value.

回答1:

The issue lies in the return type of whilestat. In the then branch, you return a function, whereas in the else branch, you return return an arbitrary piece of data. I think you simply forgot to pass all of the arguments when you recurse in the then branch.

Here's how I would write it (notice also that there's no need to use fn x => ..., which I think contributed to your confusion).

fun whilestat test stmt1 x =
  if test x
  then (stmt1 x; whilestat test stmt1 x)
  else x

In the future, you might find it helpful to explicitly annotate types in your source code, to double check your reasoning. I found your bug by trying to fill in the ??? below:

fun whilestat (test : 'a -> bool) (stmt1 : 'a -> unit) : ??? =
  ...