Haskell在不同GHC版本中的多态函数

lsmepo6l  于 2024-01-08  发布在  其他
关注(0)|答案(1)|浏览(196)

我在MacOS(M2 GPU)的haskell中开发vulkan应用程序。
代码width = realToFrac (width (swapchainExtent :: Extent2D))在以下项目(vulkan)https://github.com/expipiplus1/vulkan/blob/2007a6ebca9a585028163a850bcedef856fc1e94/examples/sdl-triangle/Main.hs#L283C66-L283C74
ghc 8.10.7中编译成功。
但是ghc 9.6.3中的错误。
错误消息为

  1. /Users/liuzichao/Hulkan/test/Main.hs:283:40: error:
  2. Ambiguous occurrence width
  3. It could refer to
  4. either the field width of record Viewport’,
  5. imported from Vulkan.Core10 at test/Main.hs:36:1-30
  6. (and originally defined in Vulkan.Core10.Pipeline’)
  7. or the field width of record FramebufferCreateInfo’,
  8. imported from Vulkan.Core10 at test/Main.hs:36:1-30
  9. (and originally defined in Vulkan.Core10.Pass’)
  10. or the field width of record Extent3D’,
  11. imported from Vulkan.Core10 at test/Main.hs:36:1-30
  12. (and originally defined in Vulkan.Core10.FundamentalTypes’)
  13. or the field width of record Extent2D’,
  14. imported from Vulkan.Core10 at test/Main.hs:36:1-30
  15. (and originally defined in Vulkan.Core10.FundamentalTypes’)
  16. |
  17. 283 | , width = realToFrac (width (swapchainExtent :: Extent2D))
  18. |

字符串
为什么会发生这种情况?如果ghc 9.6.3ghc 8.10.7有什么不同?

dw1jzc5e

dw1jzc5e1#

是的,我遇到了同样的问题,试图遵循一些Vulkan的例子。
基于this proposal的记录字段正在进行大量更改,这需要模糊的字段名称变得更加模糊。我发现GHC更改日志中的文档不完整,并且对于该提案的哪些部分正在与GHC的哪些版本一起推出感到困惑。
但是,GHC 8.10.7接受以下程序:

  1. {-# LANGUAGE DuplicateRecordFields #-}
  2. module Field where
  3. data Rect = Rect { width :: Int, height :: Int }
  4. data Circle = Cirlce { width :: Int }
  5. biggerRect :: Rect -> Rect
  6. biggerRect r = r { width = 2 * width (r :: Rect) }

字符串
在GHC 9.2.1中编译但抛出一些警告(与使用更新语法width = ...而不是width (r :: Rect)访问有关),并被9.4.1完全拒绝:

  1. Field.hs:9:32: error:
  2. Ambiguous occurrence width
  3. It could refer to
  4. either the field width of record Circle’,
  5. defined at Field.hs:6:24
  6. or the field width of record Rect’, defined at Field.hs:5:20
  7. |
  8. 9 | biggerRect r = r { width = 2 * width (r :: Rect) }
  9. | ^^^^^


最简单的修复方法是使用OverloadedRecordDot扩展(从GHC 9.2.0开始可用),它允许您编写:

  1. {-# LANGUAGE OverloadedRecordDot #-}
  2. biggerRect :: Rect -> Rect
  3. biggerRect r = r { width = 2 * r.width }


这仍然会在width = ...更新部分抛出警告,但它会编译。
对于上面的示例,以下方法有效:

  1. , width = realToFrac swapChainExtent.width


并且不生成警告,因为这是构造函数调用的一部分,而不是记录更新。

展开查看全部

相关问题