mneumann
mneumann

Reputation: 786

"Expression type 'Bool' is ambiguous without more context" in ternary operation

I am trying to pass an enum to a function that does an operation on that enum's arguments. I receive this error:

Expression type 'Bool' is ambiguous without more context

The same error happens in an equivalent if clause, so it's not the ternary operator itself that causes the problem.

enum auto {
        case pkw (SerialNumber: String, Axles: Int, Weight: Float)
        case lkw (SerialNumber: String, Axles: Int, Weight: Float)
}

func checkIntegrity(car: auto) -> Bool {
        switch car {
        case .pkw:
            if (checkSerialNumber(serialNumber: .pkw.SerialNumber.rawValue)
                && checkWeight(weight: .pkw.Weight.rawValue)) { // Error here, "&&" is underlined
                    return true
                } else {
                    return false
                }
            break;
        case .lkw:
            return (checkSerialNumber(serialNumber: .lkw.SerialNumber.rawValue)
                && checkWeight(weight: .lkw.Weight.rawValue)) ? true : false; // same error here, "&&" is underlined
            break;
        default:
            return false
}

The other functions that are called just return a Bool:

func checkSerialNumber(serialNumber: String) -> Bool {
        return serialNumber.contains("ABABWA") // changed after a hint in the comments
}

func checkWeight(weight: Float) -> Bool {
        return (weight < 2)
}

I am suspecting something wrong with the enum and how I use them, but I haven't found the solution yet.

Upvotes: 1

Views: 1350

Answers (1)

Martin R
Martin R

Reputation: 539695

The error message is misleading. You want to check the associated values of an enumeration value, therefore you must bind those in the case pattern:

func checkIntegrity(car: auto) -> Bool {
    switch car {
    case let .pkw(serialNumber, _, weight):
        if checkSerialNumber(serialNumber: serialNumber)
            && checkWeight(weight: weight) {
            return true
        } else {
            return false
        }
        break;
    case let .lkw(serialNumber, _, weight):
        return (checkSerialNumber(serialNumber: serialNumber)
            && checkWeight(weight: weight)) ? true : false;
        break;
    default:
        return false
    }
}

This can be simplified to

func checkIntegrity(car: auto) -> Bool {
    switch car {
    case let .pkw(serialNumber, _, weight),
         let .lkw(serialNumber, _, weight):
        return checkSerialNumber(serialNumber: serialNumber) && checkWeight(weight: weight)
    }
}

Upvotes: 3

Related Questions