ここでの問題は、デフォルトでは、Haskell で値を出力できないことです。print
関数や GHCi REPL などで使用されるものを出力するデフォルトの方法はshow
、型 class で定義された関数Show
です。
Show
取得しているエラーは、定義済みのインスタンスを持たない型の式を評価したことを通知しています。いくつかの言い回しをモジュロすると、これがすべてのエラーメッセージが言っていることです:
No instance for (Show ((t -> t1) -> t -> t1))
型((t -> t1) -> t -> t1)
は、評価した式に対して推測されたものです。これは教会の数字 1 の有効な型ですが、教会の数字の「正しい」型は実際には(a -> a) -> a -> a
です。
arising from a use of `print' at <interactive>:1:0-1
関数を暗黙的に使用しprint
て値を表示しています。通常、これはプログラムのどこでエラーが見つかったかを示しますが、この場合は<interactive>:1:0-1
、エラーが REPL の式によって引き起こされたことが示されています。
Possible fix:
add an instance declaration for (Show ((t -> t1) -> t -> t1))
これは、予期していたインスタンスを定義することでエラーを修正できることを示唆しているだけです。
さて、なぜできないのかを知るだけでなく、実際に教会の数字を印刷したいと思うでしょう。残念ながら、これは要求されたインスタンスを追加するほど単純ではありません: のインスタンスを書くと(a -> a) -> a -> a
、Haskell はこれを特定a
の のインスタンスとして解釈しますが、教会の数字の正しい解釈は、任意のa
.
つまり、show
関数を次のようにする必要があります。
showChurch n = show $ n (+1) 0
本当にしたい場合は、次のように Show インスタンスを実装できます。
instance (Show a, Num a) => Show ((a -> a) -> a -> a) where
show n = show $ n (+1) 0
{-#LANGUAGE FlexibleInstances#-}
ファイルの最初の行に追加します。または、それらを通常の数値に変換するために同様のものを実装することもできます
> churchToInt c1
1
> showChurch c1
"1"
等