如何理解和修复“无法匹配类型”错误?

时间:2019-10-14 00:08:57

标签: haskell

我正在尝试创建一个函数(conta :: Int -> Polinomio -> Int),该函数给我一个(conta n p),告诉我n中有多少p。 / p>

type Polinomio = [Monomio]
type Monomio = (Float,Int)

conta :: Int -> Polinomio -> Int
conta n [] = 0
conta n ((x,y):xs) = if n == y then x else conta xs
Ficha2.hs:83:37: error:
   • Couldn't match expected type ‘Int’ with actual type ‘Float’
   • In the expression: x
     In the expression: if n == y then x else conta xs
     In an equation for ‘conta’:
         conta n ((x, y) : xs) = if n == y then x else conta xs

Ficha2.hs:83:44: error:
   • Couldn't match expected type ‘Int’
                 with actual type ‘Polinomio -> Int’
   • Probable cause: ‘conta’ is applied to too few arguments
     In the expression: conta xs
     In the expression: if n == y then x else conta xs
     In an equation for ‘conta’:
         conta n ((x, y) : xs) = if n == y then x else conta xs

Ficha2.hs:83:50: error:
   • Couldn't match expected type ‘Int’ with actual type ‘[Monomio]’
   • In the first argument of ‘conta’, namely ‘xs’
     In the expression: conta xs
     In the expression: if n == y then x else conta xs

3 个答案:

答案 0 :(得分:4)

两个错误:

  1. conta xs应该为conta n xs。递归调用需要与初始调用相同类型的参数。
  2. conta的类型应为Int -> Polinomio -> Float,而不是Int -> Polinomio -> Int。这是因为它返回元组的第一部分,即Float

答案 1 :(得分:1)

阅读@Josepf Sible的精彩答案,您应该做的更正是:

Sub ExpireLoan()
With Workbooks("1908 AUS IC Loans Recon.xlsm").Worksheets("Control Page")
Dim currentID As Integer
Dim startID As Range
Dim endID As Range
Dim endDest As Range
Dim rowCount As Integer

'find the current loan range
    currentID = Fix(.Cells(ActiveCell.Row, 3).Value)
    Set startID = Range(.Range("C:C").Find(what:=currentID))
    Set endID = Range(.Range("C:C").Find(what:=currentID + 1))
    Set endID = Range(endID.Offset(-1, 0))

'find the last row
    Set endDest = .Range("A7").End(xlDown)
    Set endDest = endDest.Offset(-1, 0)

'copy the current loan and paste into the end of the table
    rowCount = .Range(startID, endID).Count
    .Range(startID, endID).EntireRow.Copy
    .endDest.EntireRow.PasteSpecial

'set bottom border at new end of the table
    endDest.Select
    ActiveCell.Offset(0, 0).Range("A1:AF1").Borders(xlEdgeBottom).LineStyle = xlDouble

'delete rows from loan's original position above
    .Range(startID, endID).EntireRow.Delete

'set sort ID
    ActiveCell.Offset(0, 2).Value = Fix(ActiveCell.Offset(-1, 2).Value) + 1
    For i = 0 To rowCount - 2
        ActiveCell.Offset(i + 1, 2).Value = ActiveCell.Offset(i, 2).Value + 0.1
    Next

'delete loanTypeCode
    ActiveCell.Offset(0, 1).ClearContents
    For i = 1 To rowCount - 1
        ActiveCell.Offset(i, 1).ClearContents
    Next

'fix sortID
    Set sortIdRange = Range(startID, startID.End(xlDown))
    Call subtractOneFromCells

'make it red
    ActiveCell.Offset(0, 0).Range("A1:AF1").Interior.TintAndShade = 0.399975585192419
    For i = 1 To rowCount - 1
        ActiveCell.Offset(i, 17).Range("A1:P1").Interior.TintAndShade = 0.399975585192419
    Next

End With
End Sub

示例:

type Polinomio = [Monomio]
type Monomio = (Float,Int)

conta :: Int -> Polinomio -> Float
conta n [] = 0
conta n ((x,y):xs) = if n == y then x else conta n xs

答案 2 :(得分:1)

让我们看看错误:

Ficha2.hs:83:37: error:  
   • Couldn't match expected type ‘Int’ with actual type ‘Float’
   • In the expression: x
     In the expression: if n == y then x else conta xs
     In an equation for ‘conta’:
         conta n ((x, y) : xs) = if n == y then x else conta xs

中的x有问题
if n == y then x else conta xs

问题在于x是(实际类型)Float,而实际上它本来应该是Int。它应该是Int,因为您答应要从Int返回一个conta,而xconta返回的值:

conta :: Int -> Polinomio -> Int

它是Float,因为您使用((x, y) : xs)来匹配Polinomio并最终匹配(Float, Int)。因此,从conta的第二个参数的类型中可以知道xFloat

type Polinomio = [Monomio]
type Monomio = (Float, Int)
conta :: Int -> Polinomio -> Int
conta n ((x, y) : xs) = ...