Couldn't match type ‘RideMatchinData’ with ‘Optional RideMatchinData’

I am very new to daml and I am trying to implement the findBestMatchingCandidate function from Booking a taxi ride on distributed ledgers - a smart contract example Part 2 blog post

the function is supposed to be “an Algorithmic helper that returns Optional RideMatchingData, where None indicates that no vehicle can serve the ride and Some RideMatchinData contains information about the vehicle that can serve the ride (including pickup time, drop off time and the fare).”

my implementation is as follows:

data RideMatchinData = RideMatchinData
    with
        vehicleId : VehicleId
        fare : Decimal
        pickupTime : Time
        dropoffTime : Time
    deriving (Eq, Show)

findBestMatchingCandidate : [(Vehicle, VehicleId)] -> RideRequest -> Time -> Optional RideMatchinData
findBestMatchingCandidate list rideReq time =
    foldr (\(v, vId) -> 
                        let work = (RideMatchinData with 
                                    vehicleId = vId
                                    fare = (rideReq.from.x + rideReq.from.y)
                                    pickupTime = time
                                    dropoffTime = time) 
                        in
                        if (v.lastTsLocation.space.x == rideReq.from.x) 
                        then return Some (work)
                        else return None 
            ) None list

when attempting

then return Some (work)

i get an error

"Couldn't match type ‘RideMatchinData’
                     with ‘Optional RideMatchinData’
      Expected type: RideMatchinData
                     -> Optional RideMatchinData -> Optional RideMatchinData
        Actual type: RideMatchinData
                     -> RideMatchinData -> Optional RideMatchinData"

the logic behind the function is not correct but I do not understand the error message that I am getting. Is the error possibly on the fold? I am returning an optional type on each branch of the if else so what is causing the type mismatch? Any help is appreciated, thanks!

There are two issues:

  1. The function you pass two foldr takes two arguments. The first is an element of the list, in your case that’s the tuple (v, vId), the second is the accumulator, i.e., the result of folding over all elements right of the current one. In your example, you don’t actually use the accumulator so find might be a better option but let’s go with foldr and ignore the accumulator for now.
  2. return is not the equivalent of return in languages like Java. It’s a function of type Action m => a -> m a. In your case, the typechecker infers that m = Optional so return (Some work) gives you an Optional (Optional x). The solution here is relatively straightforward: Just drop the return.

Adding things together, you end up with

findBestMatchingCandidate : [(Vehicle, VehicleId)] -> RideRequest -> Time -> Optional RideMatchinData
findBestMatchingCandidate list rideReq time =
    foldr (\(v, vId) _acc -> 
                        let work = (RideMatchinData with 
                                    vehicleId = vId
                                    fare = (rideReq.from.x + rideReq.from.y)
                                    pickupTime = time
                                    dropoffTime = time) 
                        in
                        if (v.lastTsLocation.space.x == rideReq.from.x
                        then Some work
                        else None 
            ) None list

Thank you! @cocreature