如何在 Haskell 中正确调用 GI.Gtk scrolledWindowNew?

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

documentation 说:

Usually you want to pass Nothing for the adjustments

但是

scrolled <- scrolledWindowNew Nothing Nothing

给我以下错误,可能是导入不正确造成的。

• 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)

我的导入看起来像这样

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

可能的解决方案

是不是文档有误?使用 noAdjustment 而不是 Nothing 似乎有效。

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

在 Leksah 源代码中找到灵感。

请评论

我试图将此处找到的 Python 示例翻译成 Haskell: http://python-gtk-3-tutorial.readthedocs.io/en/latest/layout.html#flowbox

问题已解决的工作版本,可以在这里找到: https://github.com/bigos/my-haskell-gtk-3-tutorial/blob/master/5-layout-containers/6-flow-box.org

如果你看一下数据的签名 GI.Gtk.Objects.ScrolledWindow.scrolledWindowNew:

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

如果你像以前那样称呼它

scrolled <- scrolledWindowNew Nothing Nothing

编译器知道关于(例如)第一个参数的两件事。它具有类型 Maybe a 并且它知道大约 a,它是某种类型,带有 IsAdjustment.

的实例

但是编译器需要确切地知道类型 a 是什么,而错误消息是因为它无法推断出来。 (遗憾的是,它很奇怪而且不是很有帮助,因为那些重叠的实例会介入。)

让我们看看为什么 noAdjustment 有效。如果我们查找它的文档 GI.Gtk.Objects.Adjustment.noAdjustment,它的类型签名为:

noAdjustment :: Maybe Adjustment

和文档状态:

A convenience alias for Nothing :: Maybe Adjustment.

Adjustment是具体类型,恰好有IsAdjustment的实例。

所以编译器很高兴,因为它现在知道参数的确切类型。

另见

What is the type of Nothing in Haskell?

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