9

定義を使用して、haskell で教会の数字を印刷しようとしています。

0 := λfx.x
1 := λfx.f x

Haskell コード:

c0 = \f x -> x
c1 = \f x -> f x

Haskellコンソールに入力すると、次のエラーが表示されます

    test> c1

    <interactive>:1:0:
    No instance for (Show ((t -> t1) -> t -> t1))
      arising from a use of `print' at <interactive>:1:0-1
    Possible fix:
      add an instance declaration for (Show ((t -> t1) -> t -> t1))
    In a stmt of an interactive GHCi command: print it

エラーの内容を正確に把握することはできません。

ありがとうございました!

4

2 に答える 2

15

ここでの問題は、デフォルトでは、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"

于 2011-06-24T02:54:00.043 に答える
6

編集:コメントで言及されているように、スポイラーアラート

または、次のようなチャーチ数のタイプを使用することもできます。

data Church x = Church ((x -> x) -> x -> x)

zero :: Church x
zero = Church (\f x -> x)

-- Hack to not clash with the standard succ
succ_ :: Church x -> Church x
succ_ (Church n) = Church (\f x -> (f (n f x)))

instance (Num x) => Show (Church x) where
  show (Church f) = show $ f (1 +) 0
于 2011-06-24T06:18:44.483 に答える