jameslintaylor
jameslintaylor

Reputation: 349

Experiments with Swift 3 operator precedence and partial function application

So I've been messing around with partial function application i.e.

func partial<A, B, C>(_ @escaping f: (A, B) -> C, _ a: A) -> (_ b: B) -> C {
    return { b in f(a, b) }
}

which is cool. I can do let equals3 = partial(==, 3) and everything works as expected

now when I try to make an operator for this in Swift 3 things are getting not so cool

infix operator •
func • <A, B, C>(_ @escaping lhs: (A, B) -> C, _ rhs: A) -> (_ b: B) -> C {
    return { b in lhs(rhs, b) }
}

let equals3 = (== • 3) raises compiler message Unary operator cannot be separated from it's operand

so I thought ok, maybe it's getting confused because these two operators == and are next to each other without declaring any precedence rules (even though in my understanding == shouldn't be considered an operator in this situation)

but still, doing

precedencegroup FunctionApplicationPrecedence {
    higherThan: ComparisonPrecedence // the precedencegroup == belongs to
}
infix operator • : FunctionApplicationPrecedence

let equals3 = (== • 3) doesn't compile and raises the same message

am I misunderstanding something here?

Upvotes: 3

Views: 209

Answers (1)

Rob Napier
Rob Napier

Reputation: 299545

So I've been messing around with partial function application

Yeah… that's probably going to go poorly… Swift lacks lots of features you would want to make that work well, and has steadily removed features (like currying syntax) that it even had. This is one of the great "you're fighting Swift" roads that we all walk down at one point or another.

That said, this has an easy fix, not unlike the fix in Haskell. You just have to put parens around the operator so the parser doesn't lose its mind. (It's probably worth opening a JIRA about the diagnostic. You should get a better error.)

let equals3 = ((==) • 3)

Or more simply:

let equals3 = (==) • 3

But oh, Swift will fight you if you keep going down this road. It'll all be roses until it's all SIG11s and expression too complex and "what do you mean there aren't higher-kinded types?"

But it's a fun road until you start throwing things, so curry on.

(If you want to see my latest walk way too far down this road, here's FP in Swift. It... works... kinda. But you fight the compiler the whole way.)

Upvotes: 2

Related Questions