当我浏览网站时: http://www.cs.princeton.edu/courses/archive/fall14/cos326/sec/03/precept03_sol.ml
根据Ocaml的结构,我有一个问题。具体来说,我对代码有疑问:
let rec reduce (f:'a -> 'b -> 'b) (u:'b) (xs:'a list) : 'b =
match xs with
| [] -> u
| hd::tl -> f hd (reduce f u tl);;
f hd
在最后一行做什么? (我知道reduce f u tl
再次调用了函数本身。)
我的第二个问题是如何使用一个函数在Ocaml中实现另一个函数。对于代码:
let times_x (x: int) (lst: int list) : int list =
map (fun y -> y*x) lst
fun y -> y*x
的作用是什么? lst
在代码末尾做什么?
谢谢您的帮助!
答案 0 :(得分:1)
The code that has been provided is a reduce function that takes three parameters - a function that maps inputs of type 'a
and 'b
to an output of type 'b
, a value of type 'b
, and as list of elements of type 'a
.
For example, the length
example from the lecture:
let length (lst: int list) : int =
reduce (fun _ len -> len + 1) 0 lst
The first parameter to reduce
is a function that, when given two parameters, discards the first one and returns the second parameter incremented by one. The second is a value (0) to be used as an accumulator. The third is a list to find the length of.
The behavior of this recursive reduce
function is to return the second parameter (an accumulator as used in the length example) once the provided list is empty, and otherwise run the provided function using the head of the list and the recursed value.
Once again going to the length
example, say we give it a list with a single element [1]
.
Our call to length
becomes reduce (fun _ len -> len + 1) 0 [1]
Recall reduce
:
let rec reduce (f:'a -> 'b -> 'b) (u:'b) (xs:'a list) : 'b =
match xs with
| [] -> u
| hd::tl -> f hd (reduce f u tl);;
First, we match [1]
against []
, which fails. Since it is a non-empty list, we run f hd (reduce f u tl)
Recall that f
is the parameter that length
provided: fun _ len -> len + 1
Therefore, we effectively run the following:
(fun _ len -> len + 1) 1 (reduce (fun _ len -> len + 1) 0 [])
In this case, the length
function discards the first parameter since the values in the list are not necessary to know the length of the list.
The recursive portion will match against []
and return the value of u
at the time, which is 0.
Therefore, one level up, (fun _ len -> len + 1) 1 (reduce (fun _ len -> len + 1) 0 [])
becomes (fun _ len -> len + 1) 1 0
and returns 0 + 1
, simplifying to our expected value 1, which represents the length of the list.
Now, to your second question, in regards to times_x
. This performs a mapping. For example, we can map [1;2;3;4;5]
to [3;6;9;12;15]
with a mapping fun x -> x * 3
.
Here times_x
is defined as follows:
let times_x (x: int) (lst: int list) : int list =
map (fun y -> y*x) lst
times_x
takes an integer and a list. Using the above example, we could call it with times_x 3 [1;2;3;4;5]
to get [3;6;9;12;15]
.
Beyond this I recommend looking into how map and reduce functions work in general.
I hope this answer was adequate at addressing your question.