1 / 18

Writing functions in ML

Writing functions in ML. Defining a simple function. MLWorks> fun add (x, y) = x + y; val add : (int * int) -> int = fn Notice what this says: add is a value the type of add is (int * int) -> int the -> denotes a function Therefore, a function is a kind of value!

clinton-cox
Download Presentation

Writing functions in ML

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Writing functions in ML

  2. Defining a simple function • MLWorks> fun add (x, y) = x + y; • val add : (int * int) -> int = fn • Notice what this says: • add is a value • the type of add is(int * int) -> int • the -> denotes a function • Therefore, a function is a kind of value! • The actual value is abbreviated to fn

  3. Another function definition • MLWorks> fun double x = 2 * x; • val double : int -> int = fn • Why don't we need parentheses around the parameter x? • Every function in ML takes one parameter and returns one result. • The parameter may be a tuple • The result may be a tuple

  4. add again • MLWorks> fun add (x, y) = x + y; • val add : (int * int) -> int = fn • MLWorks> add (7, 3); • val it : int = 10 • MLWorks> add(3.0, 5.0); • Gives a type error; why? • ML is strongly typed, but it can deduce types • If expression could be real or int, default is int

  5. Statements in ML • There are no statements in ML • ML is a purely functional language; it has no side effects*...but ML does have expressions • Every expression has a value * Except for output "statements"--we won't be doing output

  6. The if...then...else expression • ifboolean-expressionthenexpression1elseexpression2 • The else part is required (why?) • because the if expression must have a value • expression1 and expression2 must have the same type • because ML is strongly typed • it needs to know the type of the expression

  7. Using if...then...else • MLWorks> fun max(x, y) = if x > y then x else y; • val max : (int * int) -> int = fn • MLWorks> max (7, 5); • val it : int = 7

  8. Integer division, with remainder • MLWorks> fun divide(x, y) = (x div y, x mod y); • val divide : (int * int) -> (int * int) = fn • MLWorks> divide (20, 3); • val it : (int * int) = (6, 2) • We aren't returning two results, just one--but it's a tuple • Similarly, we're only providing one parameter

  9. Adding vectors • MLWorks> fun addVec ((x1, y1), (x2, y2)) = ((x1 + x2), (y1 + y2)); • val addVec : ((int * int) * (int * int)) -> (int * int) = fn • MLWorks> addVec ((3, 5), (10, 20)); • val it : (int * int) = (13, 25)

  10. LISP-like operations • Recall that ML has the following operations: • hd returns the head of a list • tl returns the tail of a list • :: adds an element to a list • These are essentially the same as CAR, CDR, and CONS in LISP • Can we define CAR, CDR, and CONS in ML?

  11. Redefining LISP • MLWorks> fun car x = hd x; • val car : 'a list -> 'a = fn • MLWorks> fun cdr x = tl x; • val cdr : 'a list -> 'a list = fn • MLWorks> fun cons (x, y) = x :: y; • val cons : ('a * 'a list) -> 'a list = fn • MLWorks> car (cdr [1,2,3,4]); • val it : int = 2

  12. Testing our LISP functions • MLWorks> cons([1,2], [3,4]); • Function applied to argument of wrong typeNear: cons (1 :: 2 :: nil, 3 :: 4 :: nil) Required argument type: (int list * int list list) Actual argument type: (int list * int list) Type clash between int and int list • Elements of list must be same type! • There is no solution (with the ML we know so far)

  13. Trapped in time • MLWorks> val age = 20; • MLWorks> fun older ( ) = age + 1; • MLWorks> older ( ); • val it : int = 21 • MLWorks> val age = 35; • MLWorks> older ( ); • val it : int = 21

  14. ML adds to state, doesn't change it • ML has no "assignment" • val age = 21; associates age with 21 • This age is then used in function older • val age = 35; associates a new age with 35 • The old age goes out of scope • ...but older still refers to the old one

  15. Functions are values, too • MLWorks> fun f x = 2 * x; • MLWorks> fun g x = f (f x); • MLWorks> g 5; • val it : int = 20 • MLWorks> fun f x = 3 * x; • MLWorks> g 5; • val it : int = 20

  16. Debugging functions • You saw that redefining a function does not affect prior uses of that function • Therefore, you can't change a function by changing something it calls • Everything should work OK if you compile all your functions from a file every time • Sometimes you just have to restart ML

  17. It's all in the binding times • ML's approach seems strange, but you have seen it before • x = 5;y = 2 * x;x = x + 1;print "y = ", y; • Would you expect y = 12 to be printed? • Remember, functions are values too!

  18. The End

More Related