Search code examples
iosswiftargo

Argo - what does mean arrow brackets in decode method?


I try to master Argo for json decoding. In documentations there is example of decode function

extension User: Decodable {
  static func decode(j: JSON) -> Decoded<User> {
    return curry(User.init)
     <^> j <| "id"
     <*> j <| "name"
    }  
}

What does <^> and <*> mean ? What is the difference between them ?


Solution

  • tldr, use <^> for the first parameter and use <*> for every parameter after that.

    Long answer: <^> is the same as Swift's map function. It's an operator borrowed from Haskell (a purely functional programming language). Although, in Haskell it's actually <$> but Swift cannot use $ in its operators so we (and others in the community) chose <^> instead.

    <^>, aka map, applies a function to a value inside a context. That context can be Optional, Array, Dictionary, or many others. In the context of Optional, <^> will apply the function in the first argument (left of the operator) to the optional value in the second argument (right side of the operator). The result will be .none if the optional value was .none or .some(x) where x is the result of the unwrapped optional value after it is passed into the function.

    I hope that makes sense. If so, <*> isn't much different except that the function in the first argument is also wrapped in a context like Optional. So you have an Optional function and an Optional value, then you would use <*>. That is why we use <*> after we use <^> for the first time, because after the first <^>, map, we're left with a partially applied constructor (a function), that has been wrapped in a context by <^>.

    <*> is taken from Haskell as well. In Haskell it is called Applicative and uses that exact same operator.