How to generate an infinite list of fibonacci numbers using curried function in SMLNJ?

余生长醉 提交于 2019-12-13 18:50:28

问题


I have coded up a general purpose routine that takes multiple arguments and generates an infinite list of fibonacci numbers which is as follows:

datatype 'a seq = Nil | Cons of 'a * (unit -> 'a seq) ;
fun fibo (a,b) = Cons(a, fn () => fibo(b,a+b));

val fib = fibo(0 , 1);

But the problem is I want to use currying technique to generate this infinite list of fibonacci numbers starting from 0 and 1, I am totally perplexed about the concept of currying.

Can some enlighten me about the concept of currying by using this example? How do I use currying to generate an infinite list of fibonacci numbers in SMLNJ?


回答1:


Here you go:

datatype 'a seq = Nil | Cons of 'a * (unit -> 'a seq) ;
fun fibo a b = Cons(a, fn () => fibo b (a + b));

val fib = fibo 0 1;

And another (very useful) curried function:

(* take n seq returns the first n items in seq. Raises Subscript if there
   are too few items. *)
fun take 0 _            = []
  | take _ Nil          = raise Subscript
  | take n (Cons (a,f)) = a :: take (n - 1) (f ())

Example (in the mosml interpreter, so it might look slightly different from SML/NJ):

- take 10 fib;
> val it = [0, 1, 1, 2, 3, 5, 8, 13, 21, 34] : int list

And just to show off a little of the power of currying:

val firstTen = take 10

- firstTen fib;
> val it = [0, 1, 1, 2, 3, 5, 8, 13, 21, 34] : int list

What happens here, is that I only give take one argument. take has type int -> 'a seq -> 'a list, so by giving it the int argument, I get something of type 'a seq -> 'a list - namely, a function that returns 10 items of the 'a seq you give it as input.




回答2:


Your definition is a little wrong as it mixes curried and uncurried forms of fibo.

If I understand correctly, there's not much to enlighten you about at the level of coding. There's a tiny syntactic difference between the curried and uncurried definitions.

- fun plus_uncurried (a, b) = a + b;
val plus_uncurried = fn : int * int -> int
- plus_uncurried (3,5);
val it = 8 : int
-  fun plus_curried a b = a + b;
val plus_curried = fn : int -> int -> int
- plus_curried 3 5;
val it = 8 : int
- val incr = plus_curried 1;
val incr = fn : int -> int
- incr 4;
val it = 5 : int

At the conceptual level, curried functions seem a little trickier, at least at first. I personally just think of a curried function as one that returns a function that wants more arguments. When you finally give the last argument you get your answer.

(I'm not sure why you tagged this question with OCaml, but in OCaml currying is the idiomatic form for functions. So you get used to it right away.)

It may be you're looking for something more complicated than a function of type int -> int -> int seq. If so, you'll need to describe a little more carefully what you're looking for. Just specifying the type of what you're looking for would probably help a lot.

Update

There's nothing more complicated in fibo than in the examples above, other than that you have a recursive call. If you just change the first part of fibo in the same way that plus_uncurried changes into plus_curried, you will have handled the definition part. To handle the calling part, change your recursive call in the same way that calls to plus_uncurried are changed into calls to plus_curried.



来源:https://stackoverflow.com/questions/19713850/how-to-generate-an-infinite-list-of-fibonacci-numbers-using-curried-function-in

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