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

发布于 2024-07-24 18:49:04 字数 1479 浏览 6 评论 0原文

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

这是代码:

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' 在 Reader monad 中运行,由 diff_op 运行,它反过来生成一个匿名函数来获取当前的 NetworkState 和来自 FAD.grad 的差分输入,并将它们填充到 Reader 中。

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

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

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.

Haskell confuses me with the following:

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

紙鸢 2024-07-31 18:49:05

这段代码给出了与您得到的相同的错误:

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

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

然而,这段代码工作正常:

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

这里,res 也被定义为多态,但仅用作Int。 仅当您以这种方式键入嵌套表达式时,编译器才会受到干扰。 在这种情况下,res 可以被重用,并且其中一个用途可能不会将其用作 Int,这与您键入嵌套表达式时不同,嵌套表达式本身无法重用。

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.

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.

掌心的温暖 2024-07-31 18:49:05

如果我写,

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

那么当计算 bigNumber :: Int 时,
它正在评估 (product :: [Int] -> Int) [(1 :: Int) .. (100 :: Int)]

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

两者之间没有任何共享。

error_diffs 只有一个类型,即:[Double] -> 网络状态 [(Int, Int, Double)]。 它必须以精确的一种方式进行评估。

但是,您所拥有的内容:

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

可以通过不同的方式进行评估,具体取决于 tag 是什么。

看到问题了吗?

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)],

and when bigNumber :: Integer is evaluated,
it's evaluating (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.

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?

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文