2018Tweet去年、WindowsでHaskellを扱う時によく遭遇するエラーと対処法という記事で、WindowsユーザーがHaskellで開発したとき、あるいはHaskell製のプログラムを使用した際によく遭遇するエラーやその回避方法を紹介しました。今回は、そこに追記したい内容として、最近私がよく出遭うようになったエラーを紹介します。長いパスをより短くするために、カレントディレクトリーを変更して、相対パスを短くする。APIのユニコード版の関数に、\\?\というプレフィックスを着けた絶対パスを渡す。directory)というエラーは、本当に読んで字のごとく、開こうとしたファイルが存在しないためのエラーであることとがもちろん多いのですが、エラーメッセージに反して違う原因である場合もあります。testした際必ず問題のエラーが発生するようになってしまいました。directory)どういうことかと悩んでいたところ、こんなIssueを見つけました。Snoymanの指摘のとおり、こちらの問題はWindowsで使えるパスの長さが原因のエラーのようです。directory)なんてエラーメッセージで表されるのでわかりづらい!(おそらくWindowsのエラーコードの出し方に問題があるんじゃないかと思います)DOS時代から残るこの制限、完全に時代錯誤なものでしかないのですが、Windowsでパッケージマネージャーなどが自動的に作ったパスを扱っていると、しばしば出くわすことがあります。1.6.5のChangeLogでも言及されていたりと、至る所で格闘している跡があります。directory)ですが、残念ながら私が知る限り、プロジェクトなどのパスを(C:\などのよりルートに近い場所に置いて)より短くする以外の回避方法はありません。10であれば、グループポリシーを編集して、「Win32の長いパスを有効にする」を「有効」にすれば回避できるとのことですが、残念ながら手元で試した限りうまくいきませんでした。何かやり方がまずかったのかもしれませんが。buildコマンドなどを実行したときに問題のエラーに遭遇した場合、ビルドしたいもののパスをなんとかして短くする以上の方法はありません。C:\直下をホームディレクトリのように使う人が今でもたくさんいるわけです。あなたが問題のエラーが発生するプログラムを修正することができる立場にある場合、次の方法で回避できるかもしれません。tohere長いパスをより短くするために、カレントディレクトリーを変更して、相対パスを短くする。本件はあくまでも、Windowsの各種ファイル操作用APIの1回の呼び出しで渡せる長さの制限ですので、制限を超えてしまうような場合はパスを分割すればよいのです。filepathパッケージのsplitFileName関数やsplitPath関数を駆使してパスを分割した上で、対象のファイルの親ディレクトリーまでdirectoryパッケージのsetCurrentDirectory関数で移動すれば、制限に引っかからないはずです(時間の都合でこちらについては試すコードを用意しておりません。残念ながらカレントディレクトリーはプロセス全体で共有される情報ですので、マルチスレッドなプログラムでは頭の痛い問題が出てきてしまいますが、一番確実に回避できる方法のはずです。マルチスレッドである場合を考慮したくない場合は、次に紹介する方法を検討するとよいでしょう。APIのユニコード版の関数に、\\?\というプレフィックスを着けた絶対パスを渡す。API」と呼ばれるWindows固有のAPI群の一部です。(Windows)をご覧ください)。このうち、「ユニコード版」のAPIには、この制限を緩和する専用の機能が含まれています。先ほども触れたMSDNのページ曰く、なんと\\?\という変な文字列を絶対パスの頭に着けると、最大約32,767文字のパスまで受け付けるようになるというのです!なんともアドホックな感じのする解決方法ですが、Microsoftが言うんだから間違いありません。いずれにしても32,767文字という微妙な最大文字数ができてしまいますが、UTF-16での32,767文字なので、そう簡単に超えることはないでしょう。いちいち絶対パスに変えて変なプレフィックスを加えないといけないという面倒くささはありますが、いちいち分割して相対パスに変換するよりは簡単なはずですので、検討する価値があります。@matsubara0507!)。catch関数を使って例外を捕捉している箇所では、実際にパスが長すぎるためにエラーが発生し、catchされているはずです。tohereおわりにさて、またしてもWindows固有の面倒な問題を紹介することとなってしまいましたが、俗世の喜び(主にゲーム)と簡単にインストールできるGUIに慣らされてしまった私は、今後もWindowsを使い続けるつもりです。ライセンスの下に提供されています。Analyticsでアクセス情報を収集しています。集めた情報は統計的に処理した上で、当ウェブサイトの改善のための参考情報としてのみ使用します。