I'm working my way through the Red Book, trying to do some of the exercises in Kotlin. In chapter 9, there's an example that uses a type constructor (the book itself uses Scala).
trait Parsers[ParseError, Parser[+_]] {
def run[A](p: Parser[A])(input: String): Either[ParseError,A]
}
I've tried to express this using Arrow as below:
class ForParser private constructor()
typealias ParserOf<T> = Kind<ForParser, T>
inline fun <T> ParserOf<T>.fix(): Parser<T> = this as Parser<T>
class Parser<A>(val v: A) : ParserOf<A>
interface Parsers<ParseError> {
fun <A> run(p : Parser<A>) : (String) -> Either<ParseError, A>
fun char(c : Char) : Parser<Char>
}
So, this is my first pass which actually doesn't give any compile-time errors. But I'm confused by a few points:
• Parsers interface is now only generic on the error and not on the Parser, what am I missing and how do I express it?
• What is the syntax for the annotation
@higherkind
to eliminate the first three lines of boilerplate? If I just annotate the Parser class, ParserOf is flagged as undefined.
• I'm not calling fix() anywhere, would I do that in the concrete implementation?
• Scala seems to have a nice syntax for declaring curried functions and I've eliminated the named parameter input when I translated the run function. Is there a better way to express this?
BTW Found this talk really helpful
https://yowconference.com/talks/jacob-bass/yow-lambda-jam-2018/higher-kinded-types-in-a-lower-kinded-language-functional-programming-in-kotlin-code-jam-6368/