データ構築子さんの事・・・分からなく成っちゃった・・・

分からなくなるもなにも、最初から何も知らん!!!!!!!

data Bool :: * where
  true :: Bool
  false :: Bool

みたいな事を書いた時、このtrueとかfalseさんて一体何者なんだろうっていう雰囲気。

例えば、

data Bool :: * where
  true :: Nat
  false :: Nat

これではダメなのか?っていう話がある。Boolなんてクソクラエじゃい!!という。

で、そもそもデータ構築子(上の例だとtrue、false)には実装を書いていないとかっていうのが何とも酷い話だよなーと思っていて。

それから、上の例だと、trueとfalseはBool型の「値」です、って言われて、まぁそうだろうなぁと思うけれども、じゃあ一方で

data Nat :: * where
  zero :: Nat
  succ :: Nat -> Nat

のsuccっていうのは、Natの値なんか?って言われて、うーんていう謎の気持ちになる。

で胡散臭いのが良く分からんて感じで、実装書かなくても良いよーっていう事に対する辻褄合わせとしては多分これは全部Variant/Tagged Disjoint Sum/Tagged Disjoint Unionにぶち込んでるに過ぎないそれなんじゃないだろうか。

だから上の例でtrueとかfalseっていうのは実は、っていうかBoolが実は

Bool は variant {true_ :: Unit,false_ :: Unit} つまり true_ + false_と等しい。

で、
true :: Bool
true = variant { true_ = () } -- ()はUnitの値。
fales :: Bool
false = variant { false_ = ()} -- ()はUnitの値。

みたいに成っていれば、辻褄が多分合う。

Natも同様で

Nat は variant { zero_ :: Unit, succ_ :: Nat} つまり zero_ + succ_と等しい

で、
zero :: Nat
zero = variant { zero_ = () }
succ :: Nat -> Nat
succ n = variant {succ_ = n }

じゃあNat型のListはどうよみたいなのは、Haskellで書くと

data NatList :: * where
  nil :: NatList
  cons :: Nat -> NatList -> NatList

これが

NatList は {nil_ :: Unit, cons_ :: (Nat,NatList) } つまり nil_ + cons_と等しい
ここで(Nat,NatList)はNat型とNatList型のtuple,組

で、
nil :: NatList
nil = variant {nil_ = ()}
cons :: Nat -> NatList -> NatList
cons n nl = variant {cons_ = (n,nl)}

みたいなそれだと良いんじゃないかなーとか。

もちろんvariantさんから値を抜き出す時は、caseとか、まぁ。

でなんでこんな事を考えていたかというと、Agda2では陽に代数データ型を書けるけれども、ITTnにはそんなものはなくて、ITTnにある範疇で考えるとどうなるんだろうなーって事を考えると上みたいな事に。

ITTnにはDisjoint Sumがあるので、その自然な拡張で出来るんだろうなーみたいな事で、なんかなぁ・・・。

というか、HaskellはKindあるんだなーと改めて思ったのでした。

data Hoge :: * -> * where
  hoge :: Nat -> Bool -> Hoge Nat
  foo  :: Nat -> Bool -> Hoge Bool

しかしこれだとなぁ・・・。

Hoge :: * -> *
Hoge = variant {hoge_ :: (Nat,Bool) , foo_ :: (Nat,Bool)}

として

hoge :: Nat -> Bool -> (Hoge,Nat)
hoge n b = (Hoge_,Nat)
  where
    Hoge_ :: Hoge
    Hoge_ = variant {hoge_ = (n,b)}

foo :: Nat -> Bool -> (Hoge,Bool)
foo n b = (Hoge_,Bool)
  where
    Hoge_ :: Hoge
    Hoge_ = variant {foo_ = (n,b)}

胡散臭過ぎる!!

Hogeは型コンストラクタに見えるけど、上の層から見るとデータコンストラクタだし、これもまたVariantで押し込んで

* = {Hoge : *, ...他の型コンストラクタ達 }

とかで良さそうな気も。

あとは

{-
data Hoge : Set0 where
  hoge : (Nat , Bool) -> Hoge
  foo  : (Nat , Bool) -> Hoge

TypeConstHoge : Set0 -> Set0
TypeConstHoge T = Hoge
の方でも

HogeがVariantっぽく素直に書けるし、かつデータコンストラクタの型がカッチリ決まるので
-}

data _+_ (P Q : Set0) : Set0 where -- 結局これが説明出来なくなるとかは無しで!!Variant作れる仮定で
  hoge : P -> P + Q
  foo  : Q -> P + Q

record _,_ (P Q : Set0) : Set0 where
  field
    fst : P
    snd : Q

Hoge : Set0 -> Set0
Hoge T = (Nat , Bool) + (Nat , Bool)

const_hoge : Nat -> Bool -> Hoge Nat
const_hoge n b = hoge (record {fst = zero; snd = true})

const_foo : Nat -> Bool -> Hoge Bool
const_foo n b = foo (record {fst = zero; snd = true})

そもそもこんな回りくどく考えなくても良い気がして来た。

少なくともITTnでは、各型にformation ruleとintroduction ruleとelimination rule、それからequality ruleがあるんだからそれで終わりかなー。

Haskellはまぁ知らなくて、CCだと取りあえず型を定義出来ればコンストラクタの方もゴリ押し出来る気がする。

{-# LANGUAGE KindSignatures #-}
{-# LANGUAGE GADTs #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE Rank2Types #-}

data Hoge :: * where
  DataConstHoge :: (Int,Bool) -> Hoge
  DataConstFoo  :: (Int,Bool) -> Hoge

type family TypeConstHoge a
type instance TypeConstHoge Int = Hoge
type instance TypeConstHoge Bool = Hoge

hoge :: Int -> Bool -> TypeConstHoge Int
hoge i b = DataConstHoge (i,b)

foo :: Int -> Bool -> TypeConstHoge Bool
foo i b = DataConstFoo (i,b)

-- !!悲しさ
ext :: forall a.TypeConstHoge a -> a
ext (DataConstHoge (i,b)) = i
ext (DataConstFoo  (i,b)) = b
-- !!悲しさ

悲しいお知らせがあります・・・。

悲しいお知らせがあります、はトイレの花子さんで聞いて、そうポンキッキーズで昔やっていたんですけれども、誰か亡くなると、やたら亡くなるんですけれども、校内放送だとかで流れるんですが上の場合だとextが型推論出来ませんよね。

そりゃそうです・・・。そりゃそうですよ・・・。えーとだから。

data Hoge :: * -> * where
  Hoge :: Int -> Bool -> Hoge Int
  Foo  :: Int -> Bool -> Hoge Bool

ext :: forall a.Hoge a -> a
ext (Hoge i b) = i
ext (Foo  i b) = b

これがやりたい。

どうやるにせよ、どうって感じに成る。

あーーーこれ嘘だ。嘘を書いている。Agda2でやってるのは、単に型をそれっぽくしてるだけで、これは酷い。結局データコンストラクタと型が結びついてないので関数ででっち上げただけなので、extをやろうとすると死ぬ。

結局同じコードをHaskellで書き直しただけなので、同様に死んでいる。

まぁでもいいや。