Help us understand the problem. What is going on with this article?

[入門] HaskellでGUIプログラミング 導入編

HaskellでGUIプログラムを作成する方法を解説します。
具体的にはgi-gtk-declarativeというライブラリを使ってHello Worldするまでの流れを解説します。開発環境はWindows 10です。

ソースコードの詳しい解説は次の記事でする予定です。

Gtk+3開発環境の構築

https://www.msys2.org/ からMSYS2のインストーラーをダウンロードして実行します。バージョンが古いかもしれませんが、このリンクをクリックしてもインストールをダウンロードできます。
2020-10-21-22-05.png

次にMSYS2を実行してMSYSの端末を開き、必要なパッケージをインストールします。

pacman -Syy
pacman -S -q --noconfirm mingw-w64-x86_64-glade mingw64/mingw-w64-x86_64-pkg-config mingw64/mingw-w64-x86_64-gobject-introspection mingw64/mingw-w64-x86_64-gtksourceview3

最後に環境変数の設定を行います。

PATH: <msys>, <msys>/mingw64/bin, <msys>/usr/bin
PKG_CONFIG_PATH: <msys>\mingw64\lib\pkgconfig
SET XDG_DATA_DIRS: <msys>\mingw64\share

環境変数が存在しない場合は新規作成、存在する場合は追記してください。また、<msys>は先ほどMSYS2をインストールしたフォルダに置き換えてください。

stackのインストールと設定

https://docs.haskellstack.org/en/stable/README/ からインストーラーをダウンロードして実行します。このリンクをクリックしてもインストーラーをダウンロードすることができます。
2020-10-21-21-30.png

インストールが終わったら、端末(Windows Terminalなど)を立ち上げ、

cd <フォルダ>
stack new <プロジェクト名>

を実行してstackプロジェクトを作ります。このコマンドを実行すると、<フォルダ>下に<プロジェクト名>という名前のフォルダが作られます。このフォルダがプロジェクトのルートフォルダとなります。

次にエディタを開き、ルートフォルダ下のstack.yamlというファイルを編集します。

stack.yaml
resolver: lts-16.18
skip-msys: true
allow-newer: true
extra-deps:
- haskell-gi-0.24.5
- haskell-gi-base-0.24.3
- gi-harfbuzz-0.0.3
- gi-pango-1.0.23
- gi-gtk-declarative-0.6.3
- gi-gtk-declarative-app-simple-0.6.3
extra-lib-dirs: 
- <msys>\mingw64\bin
ghc-options:
  "$locals": "-threaded"

<msys>は先ほどMSYS2のインストールフォルダに置き換えてください。

さらに、package.yamlというファイルも編集します。dependenciesという項目を以下に書き換えてください。

package.yaml
dependencies:
- base >= 4.7 && < 5
- haskell-gi-base
- gi-gtk
- gi-gtk-declarative
- gi-gtk-declarative-app-simple
- pipes
- pipes-extras

GHC(Haskellのコンパイラ)をインストールします。

stack setup

最後に、ライブラリのバグを回避するためにライブラリの差し替えを行います。

まずはstackがGHCをどこにインストールしたのかを調べます。

stack path --programs

そして、ライブラリの差し替えを行います。

cp <msys>/mingw64/bin/zlib1.dll <ghc>/ghc-<version>/mingw/bin/zlib1.dll

<msys>はMSYS2のインストールフォルダに、<ghc>は先ほど調べたGHCのインストール場所に、<version>はインストールしたGHCのバージョンに置き換えてください。

ソースコードの記述

プロジェクトフォルダには既にMain.hsというファイルがあると思います。このファイルの中のmain関数がプロジェクトのエントリポイントとなります。

そのため、まずはMain.hsを書き換えます。

Main.hs
{-# LANGUAGE OverloadedStrings, OverloadedLists, OverloadedLabels #-}
module Main where

import Data.Function ( (&) )
import Data.Text ( Text )
import Pipes
import qualified Pipes.Extras as Pipes
import Control.Monad ( void )

import GI.Gtk ( Label(..), Window(..) )
import GI.Gtk.Declarative
import GI.Gtk.Declarative.App.Simple

data State = Initial | Showing Text
data Event = Show Text | Closed

view' :: State -> AppView Window Event
view' s =
    bin
        Window
        [ #title := "First Example"
        , on #deleteEvent (const (True, Closed))
        , #widthRequest := 400
        , #heightRequest := 300
        ]
    $ case s of
        Initial -> widget Label [ #label := "No message" ]
        Showing msg -> widget Label [ #label := msg ]

update' :: State -> Event -> Transition State Event
update' _ (Show msg) = Transition (Showing msg) (return Nothing)
update' _ Closed = Exit

main :: IO ()
main = void $ run App { view = view'
                      , update = update'
                      , inputs = [ greetings ]
                      , initialState = Initial
                      }
    where
        greetings =
            cycle ["Hello", "World"]
                & map Show
                & Pipes.each
                & (>-> Pipes.delay 1.0)

元々のMain.hsでは、srcフォルダのLib.hsファイルをインポートして使っていました。Main.hs書き換えたことでこのファイルは要らなくなったので削除してください。

仕上げにプロジェクトをコンパイルして実行します。

stack build
stack exec <プロジェクト名>-exe

2020-10-21-23-07.png

参考サイト

Using haskell-gi in Windows
https://github.com/owickstrom/gi-gtk-declarative/blob/master/examples/Hello.hs

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away