Search code examples
haskellgtk3

How do I properly invoke GI.Gtk scrolledWindowNew in Haskell?


The documentation says:

Usually you want to pass Nothing for the adjustments

but

scrolled <- scrolledWindowNew Nothing Nothing

gives me the following error, probably caused by incorrect imports.

• Overlapping instances for GI.Gtk.Objects.Adjustment.IsAdjustment
                              a0
    arising from a use of ‘scrolledWindowNew’   Matching instances:
    instance [overlappable] (Data.GI.Base.BasicTypes.GObject a,
                             Data.GI.Base.Overloading.UnknownAncestorError
                               GI.Gtk.Objects.Adjustment.Adjustment a) =>
                            GI.Gtk.Objects.Adjustment.IsAdjustment a
      -- Defined in ‘GI.Gtk.Objects.Adjustment’
    ...plus one instance involving out-of-scope types
    (use -fprint-potential-instances to see them all)

my imports look like this

import qualified GI.Gtk as GI (init,
                               main)
import GI.Gtk (mainQuit,
               onWidgetDestroy,
               windowNew,
               widgetShowAll,
               containerSetBorderWidth,
               headerBarNew, headerBarSetTitle, headerBarSetSubtitle,headerBarSetShowCloseButton,
               scrolledWindowNew
               )

import GI.Gtk.Objects.Window
import GI.Gtk.Enums

a possible solution

Is it an error in the documentation? Using noAdjustment instead of Nothing seems to work.

import qualified GI.Gtk as GI (init,
                               main)
import GI.Gtk (mainQuit,
               onWidgetDestroy,
               windowNew,
               widgetShowAll,
               containerSetBorderWidth,
               headerBarNew, headerBarSetTitle, headerBarSetSubtitle,headerBarSetShowCloseButton,
               scrolledWindowNew, scrolledWindowSetPolicy
               )

import GI.Gtk.Objects.Window
import GI.Gtk.Objects.Adjustment (noAdjustment)

import GI.Gtk.Enums (WindowType(..), PolicyType(..))



  scrolled <- scrolledWindowNew noAdjustment noAdjustment
  scrolledWindowSetPolicy scrolled PolicyTypeNever PolicyTypeAutomatic

Inspiration found in Leksah source code.

please comment

I was trying to translate into Haskell a Python example found here: http://python-gtk-3-tutorial.readthedocs.io/en/latest/layout.html#flowbox

Working version, with the problem solved, can be found here: https://github.com/bigos/my-haskell-gtk-3-tutorial/blob/master/5-layout-containers/6-flow-box.org


Solution

  • If you take a look at the signature of Data GI.Gtk.Objects.ScrolledWindow.scrolledWindowNew:

    scrolledWindowNew :: (HasCallStack, MonadIO m, IsAdjustment a, IsAdjustment b)  =>
                         Maybe a ->
                         Maybe b ->
                         m ScrolledWindow
    

    And if you call it like you did

    scrolled <- scrolledWindowNew Nothing Nothing
    

    The compiler knows two things about the (for example) first parameter. It has the type Maybe a and about a it know, that it is some type with an instance for IsAdjustment.

    But the compiler needs to know exactly, what the type a is and the error message is due to the fact, that it can't deduce it. (Sadly it is pretty weird and not very helpful, as those overlapping instances thingy is intervenes.)

    Let's look at, why noAdjustment works. If we look up it's documentation GI.Gtk.Objects.Adjustment.noAdjustment it type signature reads:

    noAdjustment :: Maybe Adjustment
    

    and the docs state:

    A convenience alias for Nothing :: Maybe Adjustment.

    And Adjustment is a concrete type, which happens to have an instance for IsAdjustment.

    So the compiler is happy, as it now knows the exact type of the parameters.

    Also see

    What is the type of Nothing in Haskell?

    or

    Using Haskell's "Maybe", type declarations [beginner's question]