Phil writes,
| While we are proposing things, here's a further suggestion.
| The great thing about this suggestion is that it only *removes*
| a restriction, and makes the language definition simpler.
| It is fully backward compatible.
|
| The suggestion is:
|
| Remove the restriction that type synonym
| declarations must not be recursive.
|
| In other words, one could write things like
|
| type Stream a = (a, Stream a)
|
| which is equivalent to the type (a, (a, (a, ...))).
Hear, hear! I've also run across a need for this:
nil f g = f
cons x xs f g = g x xs
fold f z xs = xs z (\x xs -> f x (fold f z xs))
fold doesn't type, but this would do the trick:
type List a b = b -> (a -> List a b -> b) -> b
nil :: List a b
cons :: a -> List a b -> List a b
(If you like existential types, replace each "List a b" above by
"List a".)
As it is, the closest I can come is
data List a b = List (b -> (a -> List a b -> b) -> b)
nil = List const
cons x xs = List (\f g -> g x xs)
fold f z (List xs) = xs z (\x xs -> f x (fold f z xs))
This is particularly bothersome, given than List is lifted. ;-)
--Joe