haskell 如何解决问题“无法将预期类型'b1'与实际类型'b'匹配”

cu6pst1q  于 2023-04-30  发布在  其他
关注(0)|答案(1)|浏览(114)

当我使用函数时,我遇到了一个问题:

plotDensity :: Forest -> ([Site] -> a -> b) -> a -> Int -> [(Int, b)]

Forest是一个具有以下类型的数据:Forest = Forest Int Int [Site]
为了回答这个问题,我键入如下代码:

plotDensity :: Forest -> ([Site] -> a -> b) -> a -> Int -> [(Int, b)]
plotDensity forest densityFunc densityArg n
  | n < 0 = error "Invalid input: n should be a non-negative integer."
  | otherwise = [(day, treeDensity day) | day <- [0 .. n]]
  where
    treeDensity :: Int -> b
    treeDensity day = callDensityFunc (sitesAfterNDays day) densityArg

    callDensityFunc :: [Site] -> a -> b
    callDensityFunc sites arg = densityFunc sites arg

    sitesAfterNDays :: Int -> [Site]
    sitesAfterNDays day = case day of
      0 -> getSites forest
      _ -> getSites (iterate updateForest forest !! day)

    -- Helper function to get the sites from the Forest data type
    getSites :: Forest -> [Site]
    getSites (Forest _ _ sites) = sites

此函数旨在为另一个Codeworld函数形成元组列表以生成密度图。但我总是得到一个错误,叫做:

src\ForestFire.hs:185:33: error:
    ? Couldn't match expected type ‘b1’ with actual type ‘b’
      ‘b1’ is a rigid type variable bound by
        the type signature for:
          callDensityFunc :: forall a1 b1. [Site] -> a1 -> b1
        at src\ForestFire.hs:184:5-39
      ‘b’ is a rigid type variable bound by
        the type signature for:
          plotDensity :: forall a b.
                         Forest -> ([Site] -> a -> b) -> a -> Int -> [(Int, b)]
        at src\ForestFire.hs:176:1-69
    ? In the expression: densityFunc sites arg
      In an equation for ‘callDensityFunc’:
          callDensityFunc sites arg = densityFunc sites arg
      In an equation for ‘plotDensity’:
          plotDensity forest densityFunc densityArg n
            | n < 0
            = error "Invalid input: n should be a non-negative integer."
            | otherwise = [(day, treeDensity day) | day <- [0 .. n]]
            where
                treeDensity :: Int -> b
                treeDensity day = callDensityFunc (sitesAfterNDays day) densityArg
                callDensityFunc :: [Site] -> a -> b
                callDensityFunc sites arg = densityFunc sites arg
                ....
    ? Relevant bindings include
        callDensityFunc :: [Site] -> a1 -> b1
          (bound at src\ForestFire.hs:185:5)
        densityFunc :: [Site] -> a -> b (bound at src\ForestFire.hs:177:20)
        plotDensity :: Forest
                       -> ([Site] -> a -> b) -> a -> Int -> [(Int, b)]
          (bound at src\ForestFire.hs:177:1)
    |
185 |     callDensityFunc sites arg = densityFunc sites arg
    |                                 ^^^^^^^^^^^^^^^^^^^^^

src\ForestFire.hs:185:51: error:
    ? Couldn't match expected type ‘a’ with actual type ‘a1’
      ‘a1’ is a rigid type variable bound by
        the type signature for:
          callDensityFunc :: forall a1 b1. [Site] -> a1 -> b1
        at src\ForestFire.hs:184:5-39
      ‘a’ is a rigid type variable bound by
        the type signature for:
          plotDensity :: forall a b.
                         Forest -> ([Site] -> a -> b) -> a -> Int -> [(Int, b)]
        at src\ForestFire.hs:176:1-69
    ? In the second argument of ‘densityFunc’, namely ‘arg’
      In the expression: densityFunc sites arg
      In an equation for ‘callDensityFunc’:
          callDensityFunc sites arg = densityFunc sites arg
    ? Relevant bindings include
        arg :: a1 (bound at src\ForestFire.hs:185:27)
        callDensityFunc :: [Site] -> a1 -> b1
          (bound at src\ForestFire.hs:185:5)
        densityArg :: a (bound at src\ForestFire.hs:177:32)
        densityFunc :: [Site] -> a -> b (bound at src\ForestFire.hs:177:20)
        plotDensity :: Forest
                       -> ([Site] -> a -> b) -> a -> Int -> [(Int, b)]
          (bound at src\ForestFire.hs:177:1)
    |

185 |     callDensityFunc sites arg = densityFunc sites arg

我想让它通过阴谋集团的v2测试,为什么会发生这种情况?我该怎么解决呢?
我认为a和B是多态的,应该包含INt和Double。是这样吗?

s2j5cfk0

s2j5cfk01#

问题是,类型变量ab来自本地签名:

callDensityFunc :: [Site] -> a -> b

被视为与顶级签名中的变量ab不同:

plotDensity :: Forest -> ([Site] -> a -> b) -> a -> Int -> [(Int, b)]

通常,您可以通过启用ScopedTypeVariables扩展并在顶级类型签名中添加forall来解决此问题:

plotDensity :: forall a b. Forest -> ([Site] -> a -> b) -> a -> Int -> [(Int, b)]

在您的情况下,您还可以通过删除本地类型签名来解决它,因为它可以被推断出来。您还必须删除treeDensity的本地类型签名。

相关问题