haskellreflex

Could not deduce (Reflex t0) arising from a use of ‘never’


Anyone knows how I could deal with errors like `Could not deduce (Reflex t0) arising from a use of ‘never’?

I am refactoring a portion of an app, which means a few never events don't get used, but since they are never to begin with, I don't care.

Can I make GHC not care somehow as well?

I know about -XExtendedDefaultRules which likely at least helps to specialize the type from forall t a. Event t a to forall t. Event t ()

And I want to specialize t as well to whatever value GHC would accept, since it results in dead code anyway.

Is there something I can write in the default (...) statement that could work? Or is that similarly impossible to writing default (IO) to specialize non-fully-specified monads to IO?

Edit: On #reflex-frp @dalaing asked for a code example, and this is what I put together for him: https://gist.github.com/Wizek/d14aada2d75637cb4f424f8a324c7ad7

Section 1 and 2 compile, 3 doesn't. But I want to make 3 compile as well since the compiler is complaining about ambiguity in something that can only be dead code.


Solution

  • Together with @dalaing on #reflex-frp we found that never :: Event t () works if -XScopedTypeVariables is enabled and the parent widget has a forall t. Reflex t => constraint or similar.

    For example, section 3 in the linked code example could be modified as such:

    {-# 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
    

    Which compiles. But it is inconvenient to have to specify the event type everywhere, and it may also not be as DRY as we want, so -XPartialTypeSignatures could help via never :: Event t _

    Or even better, I find, we can do never @t with -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
    

    So from this point onwards, I might just make it a policy that in my reflex related code portions I never write never, and always write (never @t), which solves this problem perfectly for the most part.

    I just still wish GHC could be asked to be more lenient in type checking dead code in general, not just when it comes to reflex, but perhaps that is impossible for now.