🗂

Windows PCにHaskellプログラミング環境を作る(2023/10/04版)

2023/10/04に公開
3

はじめに

この記事は、Windows 11 + WSL2:Ubuntu + VSCode をつかった Haskellプログラミング環境を構築する手順をまとめたものです。

YouTube動画を作りました(2023/10/28)

https://www.youtube.com/watch?v=adpAIvpLrRE

経緯

Windows PCでプログラミングを始めようという方々とHaskellプログラミングを楽しもうということになったので、Windows PCにHaskellプログラミング環境が必要になりました。筆者は、普段 Pop!_OS (Ubuntu系Linux)システム上でHaskellプログラミングを楽しんでいます。今回は、Windowsには不慣れということもあって、Windowsネイティブなシステム上に作ったわけではなく、Windows Subsystem for LinuxにインストールしたUbuntu上に構築したものです。

手順どおり進めれば、すんなりできるはずでしたが、以下でもたつきました。

WSL2の不具合はそのうち修正されると思いますが、とりあえずの回避方法を見つけましたので、該当箇所で紹介しています。

デバイス仕様概要

項目 内容
プロセッサ AMD Ryzen 7 6800U with Radeon Graphics 2.70 GHz
実装RAM 16GB
OS Windows 11 Home 22H2

手順概要

  1. Windows 11
    1. Windows Update の実施
    2. プログラミングフォント白源(はくげん/HackGen) のインストール
  2. Visual Studio Code (VSCode)
    1. インストール
    2. 拡張機能
  3. WSL
    1. WSL:Ubuntu のインストールと更新
    2. プログラミング用基本パッケージのインストール
    3. Haskellプログラミング環境

Windows11

Windows Update の実施

なにはともあれ、基盤となるWindows 11を最新の状態にしておきましょう。

  • 「スタート」—「設定」—「Windows Update」

再起動が必要な場合があります。

プログラミング用フォント白源(HackGen)のインストール

視認性のよいフォントを利用すると気持ちよくプログラミングができます。フォントについて必須ではありません。白源(HackGen)は筆者の好みによるお勧めです。

  • ダウンロード:
  • 展開:
    • ファイルエクスプローラで「ダウンロード」フォルダを開いて、HackGen_NF_v2.9.0.zipというファイルを選択します。
    • ツールバーにある「すべて展開」をクリック
    • 展開先などはそのままで、「展開」ボタンをクリック
  • インストール:
    • 展開が済むと、HackGen_NF_v2.9.0というフォルダができますのでそれをダブルクリック
    • .ttfというファイル名拡張子のついたファイルが4つ表示されるので、Ctrl+A[2]で、すべて選択した状態にする
    • 選択されたフォントファイル上で右クリック、メニューにある「インストール」をクリック

Visual Studio Code (VSCode) のインストールと基本設定

ダウンロード

  • サイト:Visual Studio Code - Code Editing. Redefined
  • 「Download for Windows」の青いボタンをクリックしてダウンロード
  • 「ダウンロード」フォルダにVSCodeUserSetup-x64-1.82.3.exe(2023/10/04時点でバージョンは1.82.3)が出きているので、このファイルをダブルクリックして起動
  • 「Microsoft Visual Studio Code (User) セットアップ」
    • 使用許諾契約書の同意
      • 「同意する」を選択し、「次へ」
    • インストール先の指定
      • そのまま変更せず、「次へ」
    • スタートメニューフォルダの指定
      • そのまま変更せず、「次へ」
    • 追加タスクの選択
      • その他:4つの項目すべてを✓して[3]、「次へ」
    • インストール準備完了
      • 「インストール」
    • インストール準備中 → インストール状況 → Visual Studio Code セットアップウィザードの完了
      • Visual Studio Codeを実行する に✓がついていることを確認して、「完了」

VSCode 起動

前述のインストール手順の最後で、「Visual Studio Codeを実行」に✓が付いていれば、「完了」ボタンをクリックすると VSCode が起動します。はじめてVSCodeを起動したときに Welcome Page が表示される。

  • 「Get Started with VS」のところはそのままで、左上の「< Welcome」をクリック
  • 下中央にある Show welcome page on startup の✓を外す
  • 左上タブ「Welcome ×」の「×」をクリックして Welcome page を閉じる

VSCode 日本語化

  • アクティビティバーの上から5つめ「Extensions」アイコンをクリック
  • 検索欄に Japanese と入力し、「Japanese Language Pack for Visual Studio Code」を「install」
  • 右下に出る「Change Language and Restart」のボタンをクリック
  • 再起動した VSCode のメニューなどが日本語になっていることを確認

VSCode の設定

以下に紹介する設定は、必須ではありません。筆者の好みによるお勧めです。

  • アクティビティバーの一番下、歯車の「管理」アイコンをクリック

    • メニューのなかほどにある「設定 Ctrl+,」を選択
      • よく使用するもの
        • Files: Auto Save — afterDelay に設定
        • Editor: Font Family — 'HackGen Console NF' に設定
      • 上部にある「設定の検索」欄に onEnter と入力
        • Editor: Accept Suggestion On Enter — off に設定
      • 上部にある「設定の検索」欄に minimap と入力
  • VSCodeのアイコンを右クリック、「タスクバーにビン留めする」。

設定がおわったら、VSCodeをいったん終了します。

WSL

WSL:Ubuntu のインストールと更新

インストール手順

  • タスクバーの「スタート」アイコンを右クリック
  • メニューから、「ターミナル(管理者)」をクリック
  • ターミナルのプロンプトに対して、以下のコマンドを入力[4]
    > wsl --install -d Ubuntu
    
    「Linux用Windowsサブシステム」と「Ubuntu」がインストールされます。
  • exitコマンドを入力してターミナルを終了します
  • タスクバーの「スタート」アイコンをクリック、右下の「電源」アイコンをクリック、「再起動」を選択してシステムを再起動
  • 再起動、サインインしたら、自動的にUbuntuのターミナルが起動します。
  • しばらくしたら、Ubuntuのターミナルに、Enter new UNIX username: というプロンプトが出ますので、Ubuntuで使うユーザー名を入力してください。
  • 次に、New password: というプロンプトが出ますので、パスワード(忘れないようにしてください)を入力してください。
  • 次に、Retype new password: というプロンプトが出ますので、同じパスワードを入力してください。
  • パスワードが正しく設定されれば、しばらくして、緑色の bash のプロンプトがでます。
  • exit コマンドを入力して、bashを終了します。

VSCode で WSL にリモート接続

  • VSCode に拡張機能「WSL」をインストール
    • VSCode 起動
    • アクティビティバーの上から5つめ「拡張機能」アイコンをクリック
    • 検索欄に wsl と入力し、拡張機能「WSL」を「インストール」
    • 左下の「><」(リモートウィンドウを開きます)をクリック
    • 「WSLへの接続」を選択し、クリック
    • 左下に「リモートを開いています...」と表示されて、しばらくして、「WSL:Ubuntu」になります。
    • サイドバーが、エクスプローラの表示になりますが、完全に日本語化されていない場合は、VSCodeを再起動します。
    • 再起動したら、パネルの部分にターミナルが表示され、bashの緑のプロンプトが表示されます。
    • パネルの右上にある「^」(パネルサイズの最大化)をクリックして、パネルサイズを拡げる

Ubuntu のアップデート

これ以降、WSLへ接続したVSCodeのターミナルから操作します。以降、単に「ターミナル」と言うときは、WSLへ接続したVSCodeのターミナル(シェルはbash)のことです。

  • ターミナルのbashプロンプトに対して以下のコマンドを入力[5]
    $ sudo apt update; sudo apt upgrade -y
    
    パスワードを求められたら、Ubuntuのパスワードを入力

プログラミング用基本パッケージのインストール

  • 汎用パッケージ

    • build-essential
  • FFI用

    • libffi-dev
  • 任意倍長整数演算用

    • libgmp-dev
  • 文字画面用

    • libtinfo-dev
    $ sudo apt install build-essential libffi-dev libgmp-dev libtinfo-dev
    

"DNS issues in WSL2 #8365" の回避

現時点でWSL2には、この後インストールするHaskellプログラミング用のユーティリティツールで発現する不具合DNS issues in WSL2があり、当該ツールがインターネットアクセスできなくなることがあります。この不具合は、ホストのWindows 11が参照しているDNSサーバーを利用するように/etc/resolv.confを書き換えることで回避できます[6]

  • ホストのWindows 11が参照しているDNSサーバーのアドレス
    • VSCodeのbashターミナルで以下のコマンドを実行
    $ powershell.exe Get-DnsClientServerAddress
    
    以下のような出力になります。
    InterfaceAlias         Interface Address ServerAddresses
                           Index     Family                 
    --------------         --------- ------- ---------------
    ローカル エリア接続* 1        13 IPv4    {}                                                    
    ローカル エリア接続* 1        13 IPv6    {fec0:0:0:ffff::1, fec0:0:0:ffff::2, fec0:0:0:ffff::3}
    ローカル エリア接続* 2        16 IPv4    {}                                                    
    ローカル エリア接続* 2        16 IPv6    {fec0:0:0:ffff::1, fec0:0:0:ffff::2, fec0:0:0:ffff::3}
    Wi-Fi                          6 IPv4    {192.168.3.1}                                         
    Wi-Fi                          6 IPv6    {2400:2411:8f63:a500:1111:1111:1111:1111}             
    Bluetooth ネットワーク接続    12 IPv4    {}                                                    
    Bluetooth ネットワーク接続    12 IPv6    {fec0:0:0:ffff::1, fec0:0:0:ffff::2, fec0:0:0:ffff::3}
    Loopback Pseudo-Interface 1    1 IPv4    {}                                                    
    Loopback Pseudo-Interface 1    1 IPv6    {fec0:0:0:ffff::1, fec0:0:0:ffff::2, fec0:0:0:ffff::3}
    vEthernet (WSL)               35 IPv4    {}                                                    
    vEthernet (WSL)               35 IPv6    {fec0:0:0:ffff::1, fec0:0:0:ffff::2, fec0:0:0:ffff::3}
    
    Wi-Fiを使っているので、InterfaceAlias列が「Wi-Fi」でAddressFamily列が「IPv4」であるレコードの、SeverAddresses列を見ると、192.168.3.1 が参照しているネームサーバーのアドレスであることがわかります。
    • VSCodeのターミナルで以下のコマンドを使って、/etc/resolv.confを書き換えます。
    $ echo "nameserver 192.168.3.1" | sudo tee /etc/resolv.conf
    

2023-11-04 追記

https://zenn.dev/nobsun/articles/workaround-dns-issues-in-wsl2

Haskellプログラミング環境

ようやく、本題のHaskellプログラミング環境の構築です。
GHCup というツールを使います。

GHCup のインストール

  • GHCupのインストールとツール群のインストール

    • GHCupのサイトにアクセス
    • 「To install on Windows」という方法だけが表示されるので、そのカードの下の部分にある、Show all platforms というリンクをクリック
    • 「To install on Linux, macOS, FreeBSD or WSL2」という方法が表示されるので、黒背景のコマンドラインを右にあるコピーボタン(書類が2枚のアイコン)をクリックする
    • コマンドがクリップボードにコピーされ、ボタンの背景が緑になる
    • ブラウザを閉じ、VSCodeのターミナルにCtrl+Vで貼り付ける
    • Enterキーを押してコマンドを実行
    • 続行:
      Press Enter to proceed or ctrl-c to abort.
      Note that this script can be re-run at any given time.
      
      と表示されたら、Enterキーを押す
    • 必要な PATH をホームディレクトリの .bashrc ファイルに追加:
      Detected bash shell on your system...
      Do you want ghcup to automatically add the required PATH variable to "/home/ユーザー名/.bashrc
      
      [P] Yes, prepend  [A] Yes, append  [N] No  [?] Help (default is "P").
      
      と表示される。Pをタイプ[7]してからEnterキー
    • HLSをインストール:
      Do you want to install haskell-language-server (HLS)?
      HLS is a language-server that provides IDE-like functionality
      and can integrate with different editors, shuc as Vim, Emacs, VS Code, Atom, ...
      Also see https://haskell-language-server.readthedocs.io/en/stable/
      
      [Y] Yes  [N] No  [?] Help (default is "N").
      
      と表示される。Yをタイプ[8]してからEnterキー
    • stackとGHCupをのより良い統合を行う:
      Do you want to enable better integration of stack with GHCup?
      This means that stack won't install its own GHC versions, but uses GHCup's.
      For more information see:
        https://docs.haskellstack.org/en/stableyaml_configuration/#ghc-installation-customisation-experimental
      If you want to keep stacks vanilla behavior, answer 'No'.
      
      [Y] Yes  [N] No  [?] Help (default is "Y").
      
      と表示される。Yをタイプ[9]してからEnterキー
    • インストール開始
      Press ENTER to proceed or ctrl-c to abort.
      Installation may take a while
      
      と表示される。Enterキーを押すとインストールが始まる。しばらく待つと以下が表示され、bashのプロンプトが表示される。
      All done!
      
      To start a simple repl, run:
        ghci
      
      To start a new haskell project in the current directory, run:
        cabal init --interactive
      
      To install other GHC versions and tools, run:
        ghcup tui
      
      If you are new to Haskell, check out https://www.haskell.org/ghcup/steps/
      
  • ツール群へのPATHを有効にする[10]
    ターミナルで以下のコマンドを実行

    $ source ~/.ghcup/env
    
  • GHCおよびツールのバージョンなど確認
    ターミナルで以下のコマンドを実行

    $ ghcup tui
    

    以下のようにすべて、recommended がついたものがインストールされ、デフォルトで使用するようになっているかと思います。

    ghcup tui

    とくに理由がなければ、そのままでOKでしょう。

VSCodeの拡張機能 Haskell

VSCodeに拡張機能 Haskell をインストール

  • VSCode 起動
  • アクティビティバーの上から5つめ「拡張機能」アイコンをクリック
  • 検索欄に haskell と入力し、拡張機能「Haskell」を「インストール」

確認

ここまでで、できた環境で何ができるか確認しましょう。

最初の環境first-projectを作成してみましょう。作業はVSCodeのターミナルでおこないます。

$ mkdir ~/haskell-projects
$ cd haskell-projects
$ stack new first-project

これでプロジェクトディレクトリfirst-projectができたはず。

プロジェクトディレクトリの構成

ターミナルで、

$ tree first-project

とすると以下のようにプロジェクトディレクトリの構成を判ります。

first-project
├── CHANGELOG.md
├── LICENSE
├── README.md
├── Setup.hs
├── app
│   └── Main.hs
├── first-project.cabal
├── package.yaml
├── src
│   └── Lib.hs
├── stack.yaml
└── test
    └── Spec.hs

ひとまず、first-project ディレクトリに移って、stack build コマンドを実行しましょう。

$ stack build

これで first-project-exe [11]というコマンドが作成されます。このコマンドは、標準出力に someFunc という文字列を出すだけのものです[12]。以下のように stack を使って実行します。

$ stack exec -- first-project-exe
someFunc

これで、ひとまず、Haskell プログラミング環境の構築は終了です。あとは、使いながら、自分の使いよい設定を作りましょう。

Happy Haskell Programming !
脚注
  1. ファイルエクスプローラのツールバーにある「表示」をクリック。メニューの一番下にある「表示」をクリック。「ファイル名拡張子」(項目左側にチェック✓が付いていないはず)をクリック。 ↩︎

  2. Ctrlキーを押したままAのキーをポンとたたく。 ↩︎

  3. 既定の2つだけ✓のままでも問題ありません。4項目すべて✓は筆者の好みによるお勧めです。 ↩︎

  4. 先頭の> はPowerShellのプロンプトを表しています。ユーザーがタイプすべき文字列は wsl --install -d Ubuntu です。最後に「Enter」キーを押します。 ↩︎

  5. 以降の説明ではコマンド入力行の先頭の $ は bash のプロンプトです。ユーザーが入力すべき文字列は sudo apt update; sudo apt upgrade -y です。最後に「Enter」キーを押します。 ↩︎

  6. LANのゲートウェイの設定で、パブリックDNSサーバーへのアクセスが制限されていなければ、Google Public DNS 8.8.8.8 などを利用する方法もあります。 ↩︎

  7. PATHの設定を.bashrcの最後に追加 ↩︎

  8. HLSをインストール ↩︎

  9. stackは必要なバージョンのGHCを自動的にインストールするが、このときstack独自機能ではなく、GHCupを使ってインストールを行うようにする。 ↩︎

  10. いったん、exit コマンドで bash を抜けてから、再度「パネルの切り替え」で bash を起動するという方法でも OK。 ↩︎

  11. 作成されるコマンド名を含む設定は、project.yamlというファイルに書かれています。ここでは詳細は省きます。 ↩︎

  12. こちらも、ソースコードについての説明は、ここでは省きます。 ↩︎

Discussion

harryharry

GHCup のインストールの過程でVScodeにコピペすると

sh : The term 'sh' is not recognized as the name of a cmdlet, function, script file, or operable program. Check the spelling of the name, or if a path was included, verify that the path is correct and try again.
At line:1 char:70

  • ... rl --proto '=https' --tlsv1.2 -sSf https://get-ghcup.haskell.org | sh
    • CategoryInfo : ObjectNotFound: (sh:String) [], CommandNotFoundException
    • FullyQualifiedErrorId : CommandNotFoundException

のようなエラー文が出てしまうのですが対処法がありますか?

Nobuo YamashitaNobuo Yamashita

手元では再現しないのでよくわからないですが、以下の2点を確認してみてください。

  • vscodeが、WSL:Ubuntuに接続されている
  • ターミナルには bash のプロンプト <ユーザー名>@<マシン名>:~$ が表示されている
harryharry

解決しました!ありがとうございます。
vscodeをUbuntuの環境上で開いていませんでした。