2012-02-25 10 views
1

У меня есть этот тип данных:Сведение поток в SML

datatype 'a stream' = Susp of unit -> 'a stream 
and 'a stream = Empty | Cons of 'a * 'a stream' 

, и я хочу, чтобы написать функцию, которая имеет Свести ниже типа.

flatten: ’a stream’ stream’ -> ’a stream’ 

Функция flatten будет принимать поток потоков в качестве входных данных и сгладить их, добавив их.

Как это сделать? Есть идеи?

Спасибо.

Редактировать: Я знаю, как это сделать для списков. Это довольно просто: fun flatten [] = [] | flat (l::ls) = l @ flatten ls; Помогите мне с потоками, пожалуйста, я не знаю, как шаблон сопоставить поток потока.

+0

Я предполагаю, что это домашнее задание. Я предлагаю сначала попробовать сгладить список списков, а затем адаптировать его к потокам. –

+0

@ AndreasRossberg, я знаю, как это сделать для списков. Это довольно просто: 'fun flatten [] = [] | flat (l :: ls) = l @ flatten ls; ' Помогите мне с потоками, пожалуйста, я не знаю, как шаблон сопоставить поток потока. – Dave

+1

Вы рисуете как обычно: 'fun flatten Empty = ... | flatten (Cons (x, xs)) = ... '. Вам также необходимо определить 'append' в потоках. Единственным оставшимся трюком является вставка 'fn' в нужные места. –

ответ

1

Напишем его list первый:

fun append(xs, ys) = case xs of 
    [] => ys 
    | (x::xs) => x :: append(xs, ys)    

fun flatten(xss) = case xss of 
    [] => [] 
    | (xs::xss) => append(xs, flatten(xss))    

выше должно быть очевидно. Теперь нам нужно только изменить его немного, чтобы поддержать stream, по Susp заканчивающегося и force -ную на соответствующие шаги:

fun force(Susp(xs)) = xs()           

fun append(xs, ys) = case force xs of 
    Empty => ys 
    | Cons(x,xs) => Susp(fn() => Cons(x, append(xs, ys))) 

fun flatten(xss) = case force xss of 
    Empty => Susp(fn() => Empty) 
    | Cons(xs,xss) => append(xs, flatten(xss)) 
Смежные вопросы