haskell-jp / questions #100 at 2022-04-22 20:28:55 +0900

↓のようなデータでiの型を指定せずに`show infty` みたいなことをやったとき、型のエラーとかではなく`commitAndReleaseBuffer: invalid argument (invalid character)` が出る理屈ってどなたかわかりますか?
data Point i where
  Pt    :: Integral i => i -> Point i
  Infty :: Point i

infty :: Point i
infty = Infty

instance Show i => Show (Point i) where ...
ターミナルと出力しようとしている文字コードの不一致が原因かもです
show (infty :: Point Natural) みたいに型を指定すると何事もなく表示されるんですが、show (とターミナル) の仕様と思っておけばいいんでしょうか…?もしくは表示しようとしてる文字列の出どころに依るんでしょうか?
ターミナルの文字コードを合わせるとそれはそれでエラーメッセージが文字化けするのであんまやりたくないんですよね…
ふむ 再現できるコード提示できますか?
原因は2段階あります。修正方法からして根本的なものは、 Point ii が決定できないことによるものと思われます。そして、そのエラーメッセージにおける特定の文字(よくあるのは「•」)が、対象のコンソールの文字コードで使用できなくなっていることで該当のエラーが発生しています。
いずれにしても、ご利用の環境や、再現手順の詳細が気になります。通常GHCはこのエラーを起こさないよう工夫されているので
なんとか再現できましたが、なんだか想像以上の複合要因な気がしてきました↓

Point.hs
{-# LANGUAGE GADTs #-}
module Shard.Point (
  Point,

  infty
) where

data Point i where
  Point :: Integral i => i-> Point i
  Infty :: Point i

instance Show i => Show (Point i) where
  showsPrec _ Infty     = showString "Infty"
  showsPrec _ (Point i) = shows i

infty :: Integral i => Point i
infty = Infty

Test.hs
module Main (main) where

import Shard.Point

import Test.Tasty
import Test.Tasty.HUnit

main :: IO ()
main = testCase "Infty" $ show infty @=? "Infty"

上記ファイルを適切に配置、yamlファイルたちも用意したうえで stack test すると私の環境では再現しました。

環境はWindows 11/ghc 9.0.2/stack 2.7.5/vscodeです。
chcp 65001で実行した場合は、おそらく正しいエラーが出る代わりに文字化けして
test\Test.hs:9:8: error:
    窶「 Couldn't match expected type 窶露O ()窶・with actual type 窶狼estTree窶・[0m
    窶「 In the expression: testCase "Infty" $ show infty @=? "Infty"
      In an equation for 窶藁ain窶・
          main = testCase "Infty" $ show infty @=? "Infty"
  |
9 | main = testCase "Infty" $ show infty @=? "Infty"
  |        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

となります。
うーん、想像以上に普通の環境ですね。個人的には、そのまま chcp 65001 でやるのをおすすめします。同様の問題はあちこちで見つかっては直しているので、なんで今更感がありますが、真面目に直そうと思ったらstackか何かに手を入れないといけない問題なので。
詳細: https://haskell.jp/blog/posts/2017/windows-gotchas.html
あと、やはり件の「•」が原因となっているようなので、実際のところ大抵の型エラーで発生するんじゃないかとにらんでいます。
手元に近いプロジェクトを用意して、 Test.hs を下記のように書き換えてみてもやはり再現しました。
module Main (main) where

main :: IO ()
main = putStrLn True

この状態だと依存関係もないので stack exec ghc でも十分だろう... と思って試してみましたが再現しませんでした。
これはstackがクロとみて間違いなさそうです。
ちなみに、cabalでも再現しませんでしたのでいっそのことcabalに乗り換えるのも手です。
同様のissueがあったので最小の手順をコメントしておきました
https://github.com/commercialhaskell/stack/issues/5225#issuecomment-1107455208