haskellcomboboxgtk2hs

Get ComboBox widget value in Gtk2Hs


I'm trying to get the ComboBox widget value with this code:

selectRadioB cb = do
ntxt <- comboBoxGetActiveText cb
case ntxt of
            Just ("Option 1") -> ...
            Just ("Option 2") -> ...
            Just ("Option 3") -> ... 
return ()

But, when i compile it, this error appears:

  Couldn't match type ‘[Char]’
                   with ‘text-1.2.2.0:Data.Text.Internal.Text’
    Expected type: ComboBoxText
      Actual type: [Char]
    In the pattern: "Option 1"
    In the pattern: Just ("Option 1")
    In a case alternative:
        Just ("Option 1") -> ...

How can i solve that? I've made a similay question (Create a ComboBox widget in Gtk2HS), but i dont want to use the pack fuction.

Why i cant use fromString like this?

cb <- comboBoxNewText
comboBoxAppendText cb (fromString "Option 1")
comboBoxAppendText cb (fromString "Option 2")
comboBoxAppendText cb (fromString "Option 3")
comboBoxSetActive cb 0

Thanks in advance.


Solution

  • If we look at the documentation, we see that ComboBoxText is a alias for Text:

    type ComboBoxText = Text
    

    Now Text and String are both ways to represent text, but Text does this in a compact way, whereas String (which is actually an alias for [Char]) does this in a linked list approach (this consumes more memory and will usually result in less efficient processing).

    Using unpack

    You can however simply use pack :: String -> Text and unpack :: Text -> String to convert between String and Text:

    pack :: String -> Text

    unpack :: Text -> String

    So you could use:

    selectRadioB cb = do
        ntxt <- comboBoxGetActiveText cb
        case fmap unpack ntxt of
                Just "Option 1" -> ...
                Just "Option 2" -> ...
                Just "Option 3" -> ... 
        return ()

    Work with OverloadedStrings

    Nevertheless this is quite inefficient: you will first convert the Text to a String, and then Haskell will perform (usually) less efficient comparisons.

    You can however use a language directive:

    {-# LANGUAGE OverloadedStrings #-}
    

    that you can put at the head of your file. Now this means that if you write a string literal Haskell can interpret this as a Text element.

    So if you write:

    {-# LANGUAGE OverloadedStrings #-}
    
    selectRadioB cb = do
        ntxt <- comboBoxGetActiveText cb
        case ntxt of
                Just "Option 1" -> ...
                Just "Option 2" -> ...
                Just "Option 3" -> ...
        return ()

    Haskell will derive that ntxt has type Maybe Text, and thus that "Option 1" should be interpreted as a Text element.

    If you use this syntax extension, you can also write:

    {-# LANGUAGE OverloadedStrings #-}
    
    -- ...
    
    cb <- comboBoxNewText
    comboBoxAppendText cb "Option 1"
    comboBoxAppendText cb "Option 2"
    comboBoxAppendText cb "Option 3"
    comboBoxSetActive cb 0
    

    So you can drop the fromString function.