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:
- The function you pass two
foldrtakes 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 sofindmight be a better option but let’s go withfoldrand ignore the accumulator for now. -
returnis not the equivalent ofreturnin languages like Java. It’s a function of typeAction m => a -> m a. In your case, the typechecker infers thatm = Optionalsoreturn (Some work)gives you anOptional (Optional x). The solution here is relatively straightforward: Just drop thereturn.
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