1

I have the following snippet I need to complete for an assignment. To fulfill the asignment I have to correctly replace the comments /*fulfill ...*/. However I tried my best and I am still getting an

missing parameter type for expanded function The argument types of an anonymous function must be fully known. (SLS 8.5) error.

I found similar questions related to this error. However I could not derive a solution for my paticular problem of those answers.

So the target is to check whether the events fulfill the properties.

I am glad for every hint.

This is the code I need to complete:

import scala.collection.mutable.MutableList

abstract class Event
case class Command(cmdName: String) extends Event
case class Succeed(cmdName: String) extends Event
case class Fail(cmdName: String) extends Event

class Property(val name: String, val func: () => Boolean)

class Monitor[T] {
    val properties = MutableList.empty[Property]

    // (propName: String)(formula: => Boolean) was inserted by me
    def property(propName: String)(formula: => Boolean) /* fulfill declaration here */ {
        properties += new Property(propName, formula _)
    }

    var eventsToBeProcessed = List[T]()

    def check(events: List[T]) {
        for (prop <- properties) {
            eventsToBeProcessed = events

            println(prop.func())                
        }
    }

    def require(func: PartialFunction[T, Boolean]):Boolean = {
        /* Fulfill body */

        // This is what I came up with and what throws the compilation error
        // case event:T => if (func.isDefinedAt(event)) Some(func(event)) else None
        // Edit 1: Now I tried this but it prints that properties evaluate to false
        var result = true
        for (event <- eventsToBeProcessed){
            if (func.isDefinedAt(event)){
                result = result && func(event)
            }
        }
        return  result
    }
}

class EventMonitor extends Monitor[Event] {
    property("The first command should succeed or fail before it is received again") {
        require {
            case Command(c) =>
                require {
                    case Succeed(`c`) => true
                    case Fail(`c`) => true
                    case Command(`c`) => false
                }
        }
    }

    property("The first command should not get two results") {
        require {
            case Succeed(c) =>
                require {
                    case Succeed(`c`) => false
                    case Fail(`c`) => false
                    case Command(`c`) => true
                }
            case Fail(c) =>
                require {
                    case Succeed(`c`) => false
                    case Fail(`c`) => false
                    case Command(`c`) => true
                }
        }
    }

    property("The first command should succeed") {
        /* Add a property definition here which requires that the first command does not fail.
         * It should yield OK with the events listed in the main method.
         */

        // This is what I came up with
        require{
            case Command(c) =>
                require{
                    case Succeed(`c`)=> true
                    case Fail(`c`) => false
                }
        }
    }
}

object Checker {

    def main(args: Array[String]) {
        val events = List(
            Command("take_picture"),
            Command("get_position"),
            Succeed("take_picture"),
            Fail("take_picture")
        )

        val monitor = new EventMonitor
        monitor.check(events)
        // Desired output should be "true false true"
    }
}
HaaLeo
  • 10,065
  • 3
  • 44
  • 55
  • `require()` is supposed to return `Boolean` but your code attempts to return `Option[T]` instead. What is being tested (matched against) that _might_ be of type `T`? – jwvh Nov 26 '18 at 21:10
  • @jwvh I extended the code: I think the target is to check whether the events fulfill the properties. With the above all properties fail instead of getting the desired output. – HaaLeo Nov 26 '18 at 22:32
  • `val func: () => Boolean` means that `func` is a function that takes no input and returns a `Boolean`. How is it supposed to select an output, **true** or **false**, if it takes no input? – jwvh Nov 27 '18 at 00:37
  • `formula: => Boolean` means that `formula` is either **true** or **false** but the determination/evaluation is done later ("[call by name](https://stackoverflow.com/a/13337382/4993128)"). I don't think that's what you want. – jwvh Nov 27 '18 at 00:40

1 Answers1

3

You wrote require function that returns T => Option[Boolean] intead of Boolean. You should rewrite it on something like this:

def require(func: PartialFunction[T, Boolean]):Boolean = {
  val left = eventsToBeProcessed.dropWhile(!func.isDefinedAt(_))
  left.headOption.forall(head => {
    eventsToBeProcessed = left.tail
    func(head)
  })
}
Aleksey Isachenkov
  • 1,230
  • 6
  • 16