Home > Mobile >  What is causing "Couldn't match expected type with actual type"
What is causing "Couldn't match expected type with actual type"

Time:11-05

The following code works:

type FirstName = String
type MiddleName = String
type LastName = String

data Name = Name FirstName LastName | NameWithMiddle FirstName MiddleName LastName

data Sex = Male | Female

showName :: Name -> String
showName (Name f l) = f    " "    l
showName (NameWithMiddle f m l) = f    " "    m    " "    l

data RhType = Pos | Neg
data ABOType = A | B | AB | O
data BloodType = BloodType ABOType RhType

showRh :: RhType -> String
showRh Pos = " "
showRh Neg = "-"
showABO :: ABOType -> String
showABO A = "A"
showABO B = "B"
showABO AB = "AB"
showABO O = "O"
showBloodType :: BloodType -> String
showBloodType (BloodType abo rh) = showABO abo    showRh rh

canDonateTo :: BloodType -> BloodType -> Bool
canDonateTo (BloodType O _) _ = True
canDonateTo _ (BloodType AB _) = True
canDonateTo (BloodType A _) (BloodType A _) = True
canDonateTo (BloodType B _) (BloodType B _) = True
canDonateTo _ _ = False --otherwise

data Patient = Patient Name Sex Int Int Int BloodType
johnDoe :: Patient
johnDoe = Patient (Name "John" "Doe") Male 30 74 200 (BloodType AB Pos)

janeESmith :: Patient
janeESmith = Patient (NameWithMiddle "Jane" "Elizabeth" "Smith") Female 28 62 140 (BloodType AB Pos)

getName :: Patient -> Name
getName (Patient n _ _ _ _ _) = n
getAge :: Patient -> Int
getAge (Patient _ _ a _ _ _) = a
getBloodType :: Patient -> BloodType
getBloodType (Patient _ _ _ _ _ bt) = bt

main = do

    let johnDoeBloodType = getBloodType(johnDoe)
    let janeESmithBloodType = getBloodType(janeESmith)

    print(canDonateTo (BloodType AB Pos) (BloodType AB Pos))
    print(canDonateTo johnDoeBloodType janeESmithBloodType)

But if I replace print(canDonateTo johnDoeBloodType janeESmithBloodType) with print(canDonateTo getBloodType(johnDoe) getBloodType(janeESmith)), it gives error:

Couldn't match expected type ‘BloodType’ with actual type ‘Patient’

Here the function's type signatures are:

canDonateTo :: BloodType -> BloodType -> Bool
getBloodType :: Patient -> BloodType

So, getBloodType(johnDoe) is considered a Patient instead of BloodType. But when I save the output of this function in johnDoeBloodType, it is considered a BloodType.

What is creating the dilemma here?

CodePudding user response:

In Haskell, f x applies the argument x to the function f.

When you write:

print(canDonateTo getBloodType(johnDoe) getBloodType(janeESmith))

...it is equivalent to:

print (canDonateTo getBloodType johnDoe getBloodType janeESmith)

Perhaps you meant:

print (canDonateTo (getBloodType johnDoe) (getBloodType janeESmith))
  • Related