thisisnotabus thisisnotabus - 11 months ago 73
Scala Question

Scala Else return function

I'm taking the Coursera FP Principles in Scala course, and I'm having trouble with the last function in the week 2 assignment. I don't want the answer, but rather some help in understanding Scala functional composition. I think I have the right idea as to how to solve the problem, I'm just getting tripped up on the Scala-specific part.

The gist is: We've been given a type alias, defined as such:

type Set = Int => Boolean

Which I've interpreted to mean a Set is a function that takes an Int and returns a Bool.

We've also been tasked with finishing the function singletonSet, which takes an int and returns a Set. I've written it as such

def singletonSet(x: Int): Set = Set(x)
val three = singletonSet(3)
three(3) //True
three(5) //False

The function I'm having trouble with is the Map function, which has this signature:

def map(s: Set, p: Int => Int): Set

Which I've interpreted to mean A function that takes a set, transforms its elements with function P, and returns a new Set.

The pesudocode: Map returns a function that takes an int, and if that int exists in Set s, return a new Set with the transformed int X (or p(x)

The actual code that's breaking:

def map(s: Set, p: Int => Int): Set = {
x =>
if (s(x)) singletonSet(p(x))
else p(x) => false

The error that I'm getting with this format is:
error: not a legal formal parameter.
Note: Tuples cannot be directly destructured in method or function parameters.
Either create a single parameter accepting the Tuple1,
or consider a pattern matching anonymous function: `{ case (param1, param1) => ... }
else p(x) => false

I'm not grokking what's wrong with my implementation. A friend wrote my logic out in Haskell and found it to be successful, so I think my algorithm is correct (although I could be wrong). I'm struggling with the Scala implementation details. Any advice or guidance is much appreciated.

Answer Source

Remember that you're dealing with a Set here, and Set is defined as a function that converts an Int to a Boolean. Therefore, your function needs to return the same thing:

def map(s: Set, p: Int => Int): Set = { 
  x => 
    if (s(x)) singletonSet(p(x))  // Returns a Set
    else p(x) => false            // Returns a Boolean

We can see that despite the input, you have two different output cases, which we know must be wrong. Now, lets also recall that you have other functions, and your definition of set and 'expand' what you're building:

def map(s: Set, p: Int => Int): (Int) => (Boolean)  //Expand 'Set' to int->boolean
  = (x: Int) => (Something that returns a boolean)

Your job is to figure out what that 'something' is, based on the semantics of map. I highly recommend looking around at other functions that return a boolean and ask how they might apply here. Specifically, you're looking for a function that will, for any integer provided, give you a transformation if that integer exists within the original set.