0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Haskellでラムダ計算:ゼロ判定

Last updated at Posted at 2024-11-19

Haskellでラムダ計算の続きです。

数がゼロの時に真、それ以外の時に僞を出力する関数$\textbf{Z}$を定義します。
$$\textbf{Z}\equiv \lambda x.x\textbf{F}\neg\textbf{F}$$

ところで、変数$a$に関数$f$をゼロ回適用したものは$a$となります。
$$\textbf{0}f a\equiv(\lambda s z.z)f a\rightarrow a$$

一方、どんな変数$a$に$\textbf{F}$に適用しても、同値関数$\textbf{I}$になってしまいます。

$$\textbf{F}a\equiv(\lambda x y.y)a\rightarrow \lambda y.y\equiv\textbf{I}$$

$\textbf{0}$に$\textbf{F}$に適用すると、$\textbf{0}\textbf{F}\neg\rightarrow\neg$を考慮して、

$$\textbf{Z0}\equiv(\lambda x.x\textbf{F}\neg\textbf{F})\textbf{0}
\rightarrow\textbf{0}\textbf{F}\neg\textbf{F}
\rightarrow\neg\textbf{F}
\rightarrow\textbf{T}$$

となります。自然数$\textbf{N}$を$\textbf{Z}$に適用すると、

$$\textbf{ZN}\equiv(\lambda x.x\textbf{F}\neg\textbf{F})\textbf{N}
\rightarrow\textbf{N}\textbf{F}\neg\textbf{F}
\rightarrow\textbf{IF}
\rightarrow\textbf{F}$$

となります。なぜなら、
$\textbf{NF}\neg
\rightarrow(\lambda fx.f^nx)\textbf{F}\neg
\rightarrow\textbf{F}^n\neg$
$\rightarrow\textbf{F}(\textbf{F}(\ldots(\textbf{F}(\textbf{F}\neg))))$
$\rightarrow\textbf{F}(\textbf{F}(\ldots(\textbf{F}(\textbf{I}))))
\rightarrow\textbf{I}$
なので。

Haskellでの実装

Haskellで書くと以下のようになりますが、iszero zeroの挙動がおかしいようです。

true x y = x
false x y = y
not' x y = x false true

zero s z = z
three s z = s(s(s(z)))

iszero x = x false not' false
add1 n = (n + 1)

main = do
    print $ iszero zero add1 1 0

つまり$\textbf{Z0}\rightarrow\textbf{T}$の型チェックがうまく行っていないようです。

ghci> :t iszero
iszero
  :: ((p1 -> p2 -> p2)
      -> (((p3 -> p4 -> p4) -> (p5 -> p6 -> p5) -> t1) -> p7 -> t1)
      -> (p8 -> p9 -> p9)
      -> t2)
     -> t2
ghci> :t three
three :: (t -> t) -> t -> t
ghci> :t iszero three

<interactive>:1:8: error:
    • Couldn't match type ‘p6’ with ‘p6 -> p6’
      Expected: ((((p3 -> p4 -> p4)
                   -> (p6 -> p6 -> p6) -> p6 -> p6 -> p6)
                  -> (p3 -> p4 -> p4) -> (p6 -> p6 -> p6) -> p6 -> p6 -> p6)
                 -> ((p3 -> p4 -> p4) -> (p6 -> p6 -> p6) -> p6 -> p6 -> p6)
                 -> (p3 -> p4 -> p4)
                 -> (p6 -> p6 -> p6)
                 -> p6
                 -> p6
                 -> p6)
                -> (((p3 -> p4 -> p4) -> (p6 -> p6 -> p6) -> p6 -> p6 -> p6)
                    -> (p3 -> p4 -> p4) -> p6 -> p6 -> p6)
                -> ((p3 -> p4 -> p4) -> (p6 -> p6 -> p6) -> p6 -> p6 -> p6)
                -> (p3 -> p4 -> p4)
                -> (p6 -> p6 -> p6)
                -> p6
                -> p6
                -> p6
        Actual: ((((p3 -> p4 -> p4)
                   -> (p6 -> p6 -> p6) -> p6 -> p6 -> p6)
                  -> (p3 -> p4 -> p4) -> (p6 -> p6 -> p6) -> p6 -> p6 -> p6)
                 -> ((p3 -> p4 -> p4) -> (p6 -> p6 -> p6) -> p6 -> p6 -> p6)
                 -> (p3 -> p4 -> p4)
                 -> (p6 -> p6 -> p6)
                 -> p6
                 -> p6
                 -> p6)
                -> (((p3 -> p4 -> p4) -> (p6 -> p6 -> p6) -> p6 -> p6 -> p6)
                    -> (p3 -> p4 -> p4) -> (p6 -> p6 -> p6) -> p6 -> p6 -> p6)
                -> ((p3 -> p4 -> p4) -> (p6 -> p6 -> p6) -> p6 -> p6 -> p6)
                -> (p3 -> p4 -> p4)
                -> (p6 -> p6 -> p6)
                -> p6
                -> p6
                -> p6
      ‘p6’ is a rigid type variable bound by
        the inferred type of
          it :: (p3 -> p4 -> p4) -> (p6 -> p6 -> p6) -> p6 -> p6 -> p6
        at <interactive>:1:1
    • In the first argument of ‘iszero’, namely ‘three’
      In the expression: iszero three
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?