如何处理“推断类型的多态性低于预期”?

时间:2022-06-01 22:01:16

I need the Numeric.FAD library, albeit still being completely puzzled by existential types.

我需要Numeric.FAD库,尽管仍然被存在类型完全困惑。

This is the code:

这是代码:

error_diffs :: [Double] -> NetworkState [(Int, Int, Double)]
error_diffs desired_outputs = do diff_error <- (diff_op $ error' $ map FAD.lift desired_outputs)::(NetworkState ([FAD.Dual tag Double] -> FAD.Dual tag Double))
                                 weights <- link_weights
                                 let diffs = FAD.grad (diff_error::([FAD.Dual tag a] -> FAD.Dual tag b)) weights

                                 links <- link_list
                                 return $ zipWith (\link diff ->
                                                       (linkFrom link, linkTo link, diff)
                                                  ) links diffs

error' runs in a Reader monad, ran by diff_op, which in turn generates an anonymous function to take the current NetworkState and the differential inputs from FAD.grad and stuffs them into the Reader.

错误'在一个Reader monad中运行,由diff_op运行,后者又生成一个匿名函数来获取当前NetworkState和来自FAD.grad的差分输入并将它们填充到Reader中。

Haskell confuses me with the following:

Haskell让我困惑如下:

Inferred type is less polymorphic than expected
  Quantified type variable `tag' is mentioned in the environment:
    diff_error :: [FAD.Dual tag Double] -> FAD.Dual tag Double
      (bound at Operations.hs:100:33)
In the first argument of `FAD.grad', namely
    `(diff_error :: [FAD.Dual tag a] -> FAD.Dual tag b)'
In the expression:
    FAD.grad (diff_error :: [FAD.Dual tag a] -> FAD.Dual tag b) weights
In the definition of `diffs':
    diffs = FAD.grad
              (diff_error :: [FAD.Dual tag a] -> FAD.Dual tag b) weights

2 个解决方案

#1


If I write,

如果我写,

bigNumber :: (Num a) => a
bigNumber = product [1..100]

then when bigNumber :: Int is evaluated,
it's evaluating (product :: [Int] -> Int) [(1 :: Int) .. (100 :: Int)],

然后当评估bigNumber :: Int时,它正在评估(product :: [Int] - > Int)[(1 :: Int)..(100 :: Int)],

and when bigNumber :: Integer is evaluated,
it's evaluating (product :: [Integer] -> Integer) [(1 :: Integer) .. (100 :: Integer)].

当评估bigNumber :: Integer时,它正在评估(product :: [Integer] - > Integer)[(1 :: Integer)..(100 :: Integer)]。

Nothing is shared between the two.

两者之间没有任何共享。

error_diffs has a single type, that is: [Double] -> NetworkState [(Int, Int, Double)]. It must evaluate in exactly one way.

error_diffs有一个类型,即:[Double] - > NetworkState [(Int,Int,Double)]。它必须以一种方式进行评估。

However, what you have inside:

但是,你有什么内容:

... :: NetworkState ([FAD.Dual tag Double] -> FAD.Dual tag Double)

can be evaluated in different ways, depending on what tag is.

可以用不同的方式进行评估,具体取决于标签。

See the problem?

看到问题了吗?

#2


this code gives the same error as you get:

此代码给出了与您相同的错误:

test :: Int
test =
  (res :: Num a => a)
  where
    res = 5

The compiler figured that res is always of type Int and is bothered that for some reason you think res is polymorphic.

编译器认为res始终是Int类型,并且由于某些原因你认为res是多态的而感到困扰。

this code, however, works fine:

但是,这段代码工作正常:

test :: Int
test =
  res
  where
    res :: Num a => a
    res = 5

here too, res is defined as polymorphic but only ever used as Int. the compiler is only bothered when you type nested expressions this way. in this case res could be reused and maybe one of those uses will not use it as Int, in contrast to when you type a nested expression, which cannot be reused by itself.

在这里,res被定义为多态,但只被用作Int。当您以这种方式键入嵌套表达式时,编译器只会受到干扰。在这种情况下,res可以重用,并且可能其中一个用途不会将它用作Int,与您键入嵌套表达式相反,后者无法自行重用。

#1


If I write,

如果我写,

bigNumber :: (Num a) => a
bigNumber = product [1..100]

then when bigNumber :: Int is evaluated,
it's evaluating (product :: [Int] -> Int) [(1 :: Int) .. (100 :: Int)],

然后当评估bigNumber :: Int时,它正在评估(product :: [Int] - > Int)[(1 :: Int)..(100 :: Int)],

and when bigNumber :: Integer is evaluated,
it's evaluating (product :: [Integer] -> Integer) [(1 :: Integer) .. (100 :: Integer)].

当评估bigNumber :: Integer时,它正在评估(product :: [Integer] - > Integer)[(1 :: Integer)..(100 :: Integer)]。

Nothing is shared between the two.

两者之间没有任何共享。

error_diffs has a single type, that is: [Double] -> NetworkState [(Int, Int, Double)]. It must evaluate in exactly one way.

error_diffs有一个类型,即:[Double] - > NetworkState [(Int,Int,Double)]。它必须以一种方式进行评估。

However, what you have inside:

但是,你有什么内容:

... :: NetworkState ([FAD.Dual tag Double] -> FAD.Dual tag Double)

can be evaluated in different ways, depending on what tag is.

可以用不同的方式进行评估,具体取决于标签。

See the problem?

看到问题了吗?

#2


this code gives the same error as you get:

此代码给出了与您相同的错误:

test :: Int
test =
  (res :: Num a => a)
  where
    res = 5

The compiler figured that res is always of type Int and is bothered that for some reason you think res is polymorphic.

编译器认为res始终是Int类型,并且由于某些原因你认为res是多态的而感到困扰。

this code, however, works fine:

但是,这段代码工作正常:

test :: Int
test =
  res
  where
    res :: Num a => a
    res = 5

here too, res is defined as polymorphic but only ever used as Int. the compiler is only bothered when you type nested expressions this way. in this case res could be reused and maybe one of those uses will not use it as Int, in contrast to when you type a nested expression, which cannot be reused by itself.

在这里,res被定义为多态,但只被用作Int。当您以这种方式键入嵌套表达式时,编译器只会受到干扰。在这种情况下,res可以重用,并且可能其中一个用途不会将它用作Int,与您键入嵌套表达式相反,后者无法自行重用。