无法推断 (Reflex t0) 是由使用“从不”引起的
Could not deduce (Reflex t0) arising from a use of ‘never’
有谁知道我如何处理因使用“never”而引起的“Could not deduce (Reflex t0)”之类的错误?
我正在重构应用程序的一部分,这意味着一些 never
事件不会被使用,但由于它们是 never
开始的,所以我不在乎。
我也可以让 GHC 不在乎吗?
我知道 -XExtendedDefaultRules
这可能至少有助于将类型从 forall t a. Event t a
专业化到 forall t. Event t ()
我还想将 t
专门化为 GHC 可以接受的任何值,因为它无论如何都会导致死代码。
我可以在 default (...)
语句中写一些有用的东西吗?或者同样不可能编写 default (IO)
来将非完全指定的 monad 专门化为 IO?
编辑:在#reflex-frp @dalaing 上要求提供代码示例,这就是我为他整理的内容:https://gist.github.com/Wizek/d14aada2d75637cb4f424f8a324c7ad7
第 1 节和第 2 节编译,第 3 节不编译。但我也想让 3 编译,因为编译器抱怨某些只能是死代码的歧义。
与#reflex-frp 上的@dalaing 一起,我们发现如果启用 -XScopedTypeVariables
并且父小部件具有 forall t. Reflex t =>
约束或类似约束,则 never :: Event t ()
有效。
例如,链接代码示例中的第 3 节可以修改为:
{-# language ScopedTypeVariables #-}
main = run 3000 $ mainWidget foo
foo :: forall t m. MonadWidget t m => m ()
foo = do
let buttonEv = never :: Event t ()
buttonEv <- button "click me"
clicksCountDy <- count buttonEv
display clicksCountDy
编译。但是必须在任何地方指定事件类型是不方便的,而且它也可能不像我们想要的那样干燥,所以 -XPartialTypeSignatures 可以通过 never :: Event t _
提供帮助
或者更好的是,我发现,我们可以 never @t
和 -XTypeApplications
:
{-# language ScopedTypeVariables #-}
{-# language TypeApplications #-}
main = run 3000 $ mainWidget foo
foo :: forall t m. MonadWidget t m => m ()
foo = do
let buttonEv = never @t
buttonEv <- button "click me"
clicksCountDy <- count buttonEv
display clicksCountDy
所以从这一点开始,我可能会制定一个策略,在我的反射相关代码部分我从不写never
,而总是写(never @t)
,这完美地解决了这个问题大部分。
我只是希望 GHC 可以被要求在一般情况下对死代码的类型检查更加宽松,而不仅仅是在涉及到反射时,但也许现在这是不可能的。
正在使用
foo :: forall t m. MonadWidget t m => m ()
foo = do
let buttonEv = never @t
buttonEv <- button "click me"
clicksCountDy <- count buttonEv
display clicksCountDy
这里never
确实不是问题。这是一个没有将动作绑定到当前 monad 的问题。有问题的行可能是任何东西:
let buttonEv = button "never click me"
这将创建一个按钮小部件操作,但永远不会 "connect" 它到当前小部件。您不会在您的应用中看到 "never click me" 按钮。
另一方面,如果您将 never
事件连接到您的小部件,
buttonEv <- return never
您将不再需要 @t
注释。
但最终,我发现 --
注释在死代码实例中效果很好。
-- let buttonEv = never
如有必要,请保留代码,但这是告诉编译器该代码不重要的最佳方式。
有谁知道我如何处理因使用“never”而引起的“Could not deduce (Reflex t0)”之类的错误?
我正在重构应用程序的一部分,这意味着一些 never
事件不会被使用,但由于它们是 never
开始的,所以我不在乎。
我也可以让 GHC 不在乎吗?
我知道 -XExtendedDefaultRules
这可能至少有助于将类型从 forall t a. Event t a
专业化到 forall t. Event t ()
我还想将 t
专门化为 GHC 可以接受的任何值,因为它无论如何都会导致死代码。
我可以在 default (...)
语句中写一些有用的东西吗?或者同样不可能编写 default (IO)
来将非完全指定的 monad 专门化为 IO?
编辑:在#reflex-frp @dalaing 上要求提供代码示例,这就是我为他整理的内容:https://gist.github.com/Wizek/d14aada2d75637cb4f424f8a324c7ad7
第 1 节和第 2 节编译,第 3 节不编译。但我也想让 3 编译,因为编译器抱怨某些只能是死代码的歧义。
与#reflex-frp 上的@dalaing 一起,我们发现如果启用 -XScopedTypeVariables
并且父小部件具有 forall t. Reflex t =>
约束或类似约束,则 never :: Event t ()
有效。
例如,链接代码示例中的第 3 节可以修改为:
{-# language ScopedTypeVariables #-}
main = run 3000 $ mainWidget foo
foo :: forall t m. MonadWidget t m => m ()
foo = do
let buttonEv = never :: Event t ()
buttonEv <- button "click me"
clicksCountDy <- count buttonEv
display clicksCountDy
编译。但是必须在任何地方指定事件类型是不方便的,而且它也可能不像我们想要的那样干燥,所以 -XPartialTypeSignatures 可以通过 never :: Event t _
或者更好的是,我发现,我们可以 never @t
和 -XTypeApplications
:
{-# language ScopedTypeVariables #-}
{-# language TypeApplications #-}
main = run 3000 $ mainWidget foo
foo :: forall t m. MonadWidget t m => m ()
foo = do
let buttonEv = never @t
buttonEv <- button "click me"
clicksCountDy <- count buttonEv
display clicksCountDy
所以从这一点开始,我可能会制定一个策略,在我的反射相关代码部分我从不写never
,而总是写(never @t)
,这完美地解决了这个问题大部分。
我只是希望 GHC 可以被要求在一般情况下对死代码的类型检查更加宽松,而不仅仅是在涉及到反射时,但也许现在这是不可能的。
正在使用
foo :: forall t m. MonadWidget t m => m ()
foo = do
let buttonEv = never @t
buttonEv <- button "click me"
clicksCountDy <- count buttonEv
display clicksCountDy
这里never
确实不是问题。这是一个没有将动作绑定到当前 monad 的问题。有问题的行可能是任何东西:
let buttonEv = button "never click me"
这将创建一个按钮小部件操作,但永远不会 "connect" 它到当前小部件。您不会在您的应用中看到 "never click me" 按钮。
另一方面,如果您将 never
事件连接到您的小部件,
buttonEv <- return never
您将不再需要 @t
注释。
但最终,我发现 --
注释在死代码实例中效果很好。
-- let buttonEv = never
如有必要,请保留代码,但这是告诉编译器该代码不重要的最佳方式。