
OK, I think I understand. You were explaining how ML could be made to emulate Haskell laziness using streams, ala Scheme type delayed evaluation, so it's kind of like you were explaining a question I hadn't quite asked yet, which maybe explains my puzzlement, I hope.
Also, though my understanding of both Haskell and ML syntax is still rudimentary, I did catch an error in your definition of chain_take: the first arg of the cons should be i rather than n.
I'm still going through your code and may have further questions.
Thanks for your input.
Michael
--- On Wed, 5/20/09, Ryan Ingram
data Stream = Stream !Int Stream -- !Int means the Int value is strict stream1 = Stream 1 stream1 stream_ints n = Stream n (stream_ints(n+1))
stream_take :: Int -> Stream -> [Int] stream_take 0 _ = [] stream_take n (Stream x xs) = x : stream_take (n-1) xs
No extra (\() -> ...) thunk is required, due to laziness :)
-- ryan
On Tue, May 19, 2009 at 4:25 PM, michael rice
Hi Ryan,
I'm afraid you've lost me. Maybe if you showed how this would be used in ML I would get the picture.
Michael
--- On Tue, 5/19/09, Ryan Ingram
wrote: From: Ryan Ingram
Subject: Re: [Haskell-cafe] showing a user defined type To: "michael rice" Cc: "Brandon S. Allbery KF8NH" , haskell-cafe@haskell.org Date: Tuesday, May 19, 2009, 2:40 PM On Tue, May 19, 2009 at 7:07 AM, michael rice
wrote: A little further along in "The Little MLer" the ints function is replaced by other functions like primes and fibs, which also return Links:
fun primes(n) = if is_prime(n+1) then Link(n+1,primes) else primes(n+1)
fun fibs(n)(m) = Link(n+m,fibs(m))
which are passed to chain_item:
fun chain_item(n,Link(i,f)) = if eq_int(n,1) then i else chain_item(n-1,f(i))
which can be called to request the nth (12th) prime number beginning at 1.
- chain_item(12,primes(1)); GC #0.0.0.1.3.61: (1 ms) val it = 37 : int -
So I guess the answer to your question about whether the function is ever called with a different value may be, yes.
Actually, it's not calling it with another value; notice that chain_item calls f(i), with i coming directly from the chain. Consider this alternate definition: (I'm not sure the syntax is exactly right, but you get the idea)
datatype chain = Link of (int * ( unit -> chain ))
fun intsFrom(n) = fun unit => (n, intsFrom (n+1)) fun ints(n) = intsFrom n ()
Now you *can't* call the function embedded in the link with another value.
fun chain_item(n,Link(i,f)) = if eq_int(n,1) then i else chain_item(n-1,f unit)
And this type for "chain" is almost the same as [Int] in Haskell, due to laziness.
-- ryan