任何人都知道我该如何处理由于无法使用而导致的错误,例如“无法推断(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编译,因为编译器抱怨某些东西只能是死代码,因此模棱两可。
答案 0 :(得分:3)
与#reflex-frp上的@dalaing一起,我们发现never :: Event t ()
在启用-XScopedTypeVariables
且父窗口小部件具有forall t. Reflex 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一般宽大地检查死代码的类型,不仅是反射方面的问题,也许现在还不可能。
答案 1 :(得分:0)
使用
foo :: forall t m. MonadWidget t m => m ()
foo = do
let buttonEv = never @t
buttonEv <- button "click me"
clicksCountDy <- count buttonEv
display clicksCountDy
这里never
确实不是问题。这是不将动作绑定到当前单子的问题。有问题的那行可能是任何东西:
let buttonEv = button "never click me"
这将创建一个按钮小部件动作,但绝不会将其“连接”到当前小部件。您不会在应用中看到“从不点击我”按钮。
另一方面,如果您将never
事件连接到窗口小部件,
buttonEv <- return never
您将不再需要@t
注释。
不过,最终,我发现--
注释在无效代码实例中效果很好。
-- let buttonEv = never
如有必要,请保留代码,但这是告诉编译器代码不重要的最佳方法。