[cpp] try some template metaprogramming
This commit is contained in:
parent
5685da9e7a
commit
bd923a9976
|
@ -0,0 +1,27 @@
|
||||||
|
#include<iostream>
|
||||||
|
|
||||||
|
template<int n>
|
||||||
|
struct Nat {
|
||||||
|
enum { val = 1 + Nat<n-1>::val };
|
||||||
|
};
|
||||||
|
|
||||||
|
template<>
|
||||||
|
struct Nat<0> {
|
||||||
|
enum { val = 0 };
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 'class' has variables 'private' by default. 'struct' has it 'public'. More
|
||||||
|
* convenient here.
|
||||||
|
*/
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
std::cout << Nat<2>::val << std::endl;
|
||||||
|
std::cout << Nat<23>::val << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Output
|
||||||
|
/*
|
||||||
|
2
|
||||||
|
23
|
||||||
|
*/
|
|
@ -0,0 +1,32 @@
|
||||||
|
#include<iostream>
|
||||||
|
|
||||||
|
struct Zero {
|
||||||
|
enum { val = 0 };
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename N>
|
||||||
|
struct Succ {
|
||||||
|
enum { val = 1 + N::val};
|
||||||
|
};
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
// O = 0
|
||||||
|
std::cout << Zero::val << std::endl;
|
||||||
|
|
||||||
|
// S O = 1
|
||||||
|
std::cout << Succ<Zero>::val << std::endl;
|
||||||
|
|
||||||
|
// S (S O) = 2
|
||||||
|
std::cout << Succ<Succ<Zero>>::val << std::endl;
|
||||||
|
|
||||||
|
// S (S (S O) = 3
|
||||||
|
std::cout << Succ<Succ<Succ<Zero>>>::val << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Output
|
||||||
|
/*
|
||||||
|
0
|
||||||
|
1
|
||||||
|
2
|
||||||
|
3
|
||||||
|
*/
|
|
@ -0,0 +1,57 @@
|
||||||
|
{-# LANGUAGE DataKinds #-}
|
||||||
|
{-# LANGUAGE GADTs #-}
|
||||||
|
{-# LANGUAGE TypeOperators #-}
|
||||||
|
{-# LANGUAGE TypeFamilies #-}
|
||||||
|
|
||||||
|
|
||||||
|
-- -- Method 1
|
||||||
|
-- data family Hlist (l :: [*])
|
||||||
|
-- data instance Hlist '[] = HNil
|
||||||
|
-- data instance Hlist (t ': ts) = HCons t (Hlist ts)
|
||||||
|
|
||||||
|
-- hd :: Hlist (t ': ts) -> t
|
||||||
|
-- hd (HCons x _) = x
|
||||||
|
|
||||||
|
-- tl :: Hlist (t ': ts) -> Hlist ts
|
||||||
|
-- tl (HCons _ xs) = xs
|
||||||
|
|
||||||
|
-- idx :: Hlist ts -> (n :: Int) -> (ts '!! n)
|
||||||
|
|
||||||
|
-- -- Can't make it work
|
||||||
|
-- -- app :: Hlist ts1 -> Hlist ts2 -> Hlist (ts1 '++ ts2)
|
||||||
|
-- -- app HNil hls2 = hls2
|
||||||
|
|
||||||
|
-- -- Can't make it work
|
||||||
|
-- -- len :: Hlist ts -> Int
|
||||||
|
-- -- len HNil = 0
|
||||||
|
-- -- len (HCons _ xs) = 1 + (len xs)
|
||||||
|
|
||||||
|
|
||||||
|
-- -- Method 2 ??
|
||||||
|
-- data HNil = HNil
|
||||||
|
-- data HCons a b = HCons a b
|
||||||
|
|
||||||
|
-- a = HCons 3 HNil
|
||||||
|
-- b = HCons 3 (HCons True HNil)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
-- Method 3
|
||||||
|
data Hlist :: [*] -> * where
|
||||||
|
HNil :: Hlist '[]
|
||||||
|
HCons :: t -> Hlist ts -> Hlist (t : ts)
|
||||||
|
|
||||||
|
data Member x (l':ls) where
|
||||||
|
First :: Member x (l:ls)
|
||||||
|
Next :: Member x ls -> Member x (l:ls)
|
||||||
|
|
||||||
|
-- data Member x (l':ls) where
|
||||||
|
-- First :: Member x (l:ls)
|
||||||
|
-- Next :: Member x ls -> Member x (l:ls)
|
||||||
|
|
||||||
|
-- len :: Hlist ts -> Int
|
||||||
|
-- len HNil = 0
|
||||||
|
-- len (HCons _ xs) = 1 + (len xs)
|
||||||
|
|
||||||
|
-- a = HCons 3 HNil
|
||||||
|
-- b = HCons 3 (HCons True HNil)
|
Loading…
Reference in New Issue