ハスケルで教会の数字を勉強しようとしています。自然数がn
という数字は基本的に次のタイプの関数を値に適用する式ですタイプt
はn
回です。考えとRankNTypesとChurch numbers
type Nat = forall t. (t -> t) -> t -> t
、私は次の方法でzero
、successor
、plus
、mult
を定義することができます。私は、べき乗を定義しようとすると
zero :: Nat
zero = \f t -> t
succ :: Nat -> Nat
succ n = \f -> f . (n f)
plus :: Nat -> Nat -> Nat
plus m n = \f -> (m f) . (n f)
mult :: Nat -> Nat -> Nat
mult m n = \f -> m (n f) -- Equal to \f -> (m . n) f
-- Pointfree version
mult' :: Nat -> Nat -> Nat
mult' = (.)
、私は同じ推論を適用してみたいのですが私は乗算を定義することができました。mult m
n
を1
に適用しました。
これは、次のコード
exp' :: Nat -> Nat -> Nat
exp' m n = n (mult m) (succ zero)
につながる。しかし、これはGHCから次のエラーで確認してください入力しない:
Couldn't match type ‘t’ with ‘t1’
‘t’ is a rigid type variable bound by
the type signature for:
exp' :: forall t. Nat -> Nat -> (t -> t) -> t -> t
at church.lhs:44:3
‘t1’ is a rigid type variable bound by
a type expected by the context:
forall t1. (t1 -> t1) -> t1 -> t1
at church.lhs:44:17
Expected type: ((t -> t) -> t -> t) -> (t -> t) -> t -> t
Actual type: Nat -> Nat
エラーは型チェッカーは、タイプのためにインスタンス化されていないと言っているようだ
n
が適切です。理想的には、式t
を別の式(t -> t
)でインスタンス化して式を実行する必要があります。また、私を混乱させているもの
次のコードtypechecksことです:
exp :: Nat -> Nat -> Nat
exp m n = n ((.) m) (succ zero) -- replace mult by (.)
誰かがここで問題に何を説明する気にしませんか? exp'
の最初の定義はtypecheckではなく、2番目のexp
のtypecheksはなぜですか?
ありがとうございます!