无法推断出由于使用“从不”而引起的(Reflex t0)

时间:2019-02-13 06:22:24

标签: haskell reflex

任何人都知道我该如何处理由于无法使用而导致的错误,例如“无法推断(Reflex t0)?”

我正在重构应用程序的一部分,这意味着一些never事件不会被使用,但是由于它们是never的开始,所以我不在乎。

我也可以使GHC不在乎吗?

我了解-XExtendedDefaultRules,这可能至少有助于使类型从forall t a. Event t aforall t. Event t ()的专业化

我还想将t专门化为GHC可以接受的任何值,因为无论如何它都会导致无效代码。

我可以在default (...)语句中写一些可行的方法吗?还是用写default (IO)来将非完全指定的monad专门用于IO同样不可能?

编辑:在#reflex-frp @dalaing上要求提供代码示例,这是我为他准备的:https://gist.github.com/Wizek/d14aada2d75637cb4f424f8a324c7ad7

第1节和第2节编译,第3节不编译。但是我也想进行3编译,因为编译器抱怨某些东西只能是死代码,因此模棱两可。

2 个答案:

答案 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

如有必要,请保留代码,但这是告诉编译器代码不重要的最佳方法。