Remix.run Logo
▲ raddan 6 hours ago

> T is not any type, T is a type defined at compile time,

This is a distinction without a difference. In a static, type-safe language, T always has to be instantiated with a type. But that does not change the fact that, from the perspective of the function definition, T is any type. T must be a specific type for the function call.

▲rcxdude 4 hours ago | parent [-]

From the function's point of view it may be asked to return any type T. That is not the same thing as it being able to return any type that is convenient for its implementation.

▲raddan 2 hours ago | parent [-]

This literally makes no sense.

▲pyrale 7 minutes ago | parent [-]

What makes no sense? To be useful, a Parser<T> needs to return a type that is useful for the consumer. If your Parser<T> returns, say, an Id or a unit, and then you combine that with a parser whose type is:

Parser<T> -> Parser<List<T>>

You'll leave your user with the task of filtering their list. If the implementer for the list parser had done the same bad job, you'd use a:

Parser<T> -> Parser<List<T>|()>

And your final type would be:

Parser<List<Id|()>|()>

That would be beyond horrible to use, and anyone using such a parser combinator library would, rightfully, be extremely annoyed.