Skip to content

Find a consistent approach to map Morphir SDK functions to valid Scala #61

Description

@AttilaMihaly

There are a number of differences in the semantics of Morphir compared to Scala which makes it challenging to come up with a consistent mapping. Let's start with a simple SDK function of List.map:

map : (a -> b) -> List a -> List b

The direct Scala mapping of this would be:

def map[A, B](f: A => B)(l: List[A]): List[B]

There are multiple things here that are not idiomatic. Here is how the idiomatic version would look like:

class List[A] {
  def map[B](f: A => B): List[B]
}

There are a number of differences between the approaches:

  • Since Scala comes from an OOP background it prefers using methods to implement functionality that belongs to a specific type so this function would normally be a method on the type itself.
  • Since Morphir is pure FP all functions are curried by default. In Scala this can be done but looks unnatural and makes type-inference more difficult.
  • Ordering of arguments is the opposite of what would be natural in Scala. In Scala the last argument would be the mapping function f. This makes type-inferencing difficult because it's generally applied left-to-right.

We can generalize the mapping approach to the following. Given this Morphir model:

type T = ...

fun : Arg1 -> Arg2 -> ...  -> ArgN -> T -> R

The generated Scala should be:

class T {
  def fun(arg1: Arg1, arg2: Arg2, ..., argN: ArgN): R
}

This will work and look natural in most cases but there are edge cases:

map2 : (a -> b -> c) -> List a -> List b -> List c

This function doesn't have a trivial method mapping since the type appears multiple times in the argument list. It seems that a better approach here is to use a static method/function but still avoid currying and put the lists into the front:

def map2[A, B, C](la: List[A], lb: List[B], f: (A,B)=> C): List[C]

This is more difficult to formalize.

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or requestquestionFurther information is requested

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions