No Such Blog or Diary

«Prev || 1 | 2 | 3 |...| 862 | 863 | 864 |...| 903 | 904 | 905 || Next»

テンプレートでリストとか

八王子からの帰り,C++のテンプレートでコンパイル時にリストを使った計算をさせようとテンプレートでリストを表現する方法を考えていた.結論としては,値を直接使わずに,全てを型の上で処理してしまえばいい.ためしにリストを作って表示,foldr, map を書いてみた.まあ,int 限定にしているけど.一般化は容易でしょう.

#include <iostream>
using namespace std;
 
#define cons(x, y)      Cons< Int< x >, y >
#define nil             Nil
 
// nil  or []
struct Nil {};
 
// cons h t  or h:t
template <typename H, typename T>
struct Cons {
    typedef H head;
    typedef T tail;
};
 
// element of lists
template<int n>
struct Int{
    enum {val = n};
    static void print() { cout << n; }
};
 
// printer
template <typename L>
struct ListPrinter {
    static void print(){
        cout << '[';
        L::head::print();
        ListPrinter<typename L::tail>::print2();
        cout << ']';
    }
    static void print2(){
        cout << ',';
        L::head::print();
        ListPrinter<typename L::tail>::print2();
    }
};
template <>
struct ListPrinter<Nil> {
    static void print(){
        cout << '[' << ']';
    }
    static void print2(){
    }
};
 
// foldr function
// foldr f e [] = e
// foldr f e (h:t) = f h (foldr f e t)
// cons case:
template<template<typename,typename> class F, typename E, typename L >
struct Foldr{
    typedef typename F<typename L::head, typename  Foldr<F,E,typename L::tail>::val >::val val;
};
// nil case:
template<template<typename,typename> class F, typename E>
struct Foldr<F,E,Nil>{
    typedef E val;
};
 
// map function
// map f [] = []
// map f (h:t) = f h:(map f t)
// cons case:
template<template<typename> class F, typename L >
struct Map{
    typedef Cons< typename F<typename L::head>::val , typename Map<F, typename L::tail>::val> val;
};
// nil case:
template<template<typename> class F>
struct Map<F,Nil>{
    typedef Nil val;
};
 
//addition operator
template <typename X, typename Y>
struct Add {
    typedef Int<X::val + Y::val> val;
};
 
// zero
typedef Int<0> Zero;
 
//douoblring operator
template <typename X>
struct Double{
    typedef Int<X::val + X::val> val;
};
 
int main(int argc, char *argv[])
{
    typedef cons(4, cons(3, cons(2, cons(1, nil)))) l;
    typedef cons(5, l) l2;
    ListPrinter< l >::print();  cout << endl;
    ListPrinter< l2 >::print(); cout << endl;
     typedef Foldr<Add, Zero, l2>::val sum;
    sum::print(); cout << endl;
     typedef Map<Double, l2>::val l3;
    ListPrinter< l3 >::print(); cout << endl;
}

とまあ,考えてみたわけだけど,あとに別の用件で google で検索かけたらThe Boost C++ Metaprogramming Libraryとかいうものを見つけてしまった.boost に含まれいてるらしいが,上で考えたのと同じで全てを型で扱ってコンパイル時計算をしているらしい.いやぁ,やっぱ同じことを考える人はいるもんだなぁ.でも,こいつにはサイズに制限があるらしい(上限を上げるようにすればいいんだけど).ということで,上の Cons/Nil は制限一切無いので捨てたもんじゃない(はず?).

エレガントプログラム賞

とある問題で書いたHaskellコードがエレガントであったとのことでエレガントプログラム賞を受賞.大変にありがたいことであります.でも,私としてはテンプレートでコンパイル時に答えを計算するようにしたものや,サンプル以外は確率的に正しいお遊びプログラムに関する賞がよかったかなぁ.今年は全体的にお遊びステートが少なかったので.ちょっと残念.

本日はHaskell講座(?)

今日のメニューはHaskell講座だったのだけど,いまさら聞く内容でもないので内職をば.昨日のHaskellで解いた問題の別解法をHaskellで実装してみたりと.やっぱ遅延評価はいいなぁ,といいたいところだけど,別解法は遅延でなくてもよかったり.まあ,無限リストの形で書いている部分では遅延評価がいるけど,これはループ変数で制御すれば有限で止まれるし.とりあえず次はモナドを使えるようになりたいなぁ.

インペリげっと

さんざ取れなかったインペリシャブルシューティングが酒に酔った勢いですんなり取れてしまった.今日中に取ってやるとか冗談で騒いどいて今日の残りも後10分という時刻からはじめ,わずか2回のトライで取れちゃいましいたとあまり面白くも無い結果に... とりあえず勝因は,酔っているせいで弾道予測が行われず,見えてる弾を予測抜きで避けたのがよかったのかと.つまりは頭を使うとだめってことだね.

ちなみにだいぶ前に書いたインペリの「ペ」が「ペ」になってたことに気づいた...  何でひらがなになったんだか意味不明だ.

今日はコードを書きました

引き続き第2第3セッションが行われたわけだが,今日は昨日の分を取り戻すようにコードをガリガリと.とりあえず昨日は残り二人のうち一人しか書いてなかったので,もう一人に一問担当してもらっといた.難しい探索問題で正しいプログアムができてから仕掛けを入れようと思ってたけどコードがなかなか出来上がらず,結局動くけど遅すぎるもので終了.最低点で残念.あとは,自分の書いたコードが原因不明のエラーを含んでいたのを抜かせば今日の出来はかなりよかった.Haskell で瞬殺できる問題があったのが効いたかな.おまけとして,やたらと書くのが面倒でただそれだけの問題を書く羽目になったけど.とりあえず,コードジェネレーターなメンバーがいたおかげで2番手にはなれたのでよしとしよう.

あの建物は…

合宿は八王子の大学セミナーハウスでやってるわけだけど存在する建物が微妙… 特別な機能も何も無くてただ形がおかしいだけの建物って迷惑なだけだ.芸術だかなんだか知らんが,実用性の無いものを実用性が望まれる場所で作るなと言いたい.そんな下らんデザインに金をかけるなら歩道とかをもっと安全に設計しろ! こけたら谷底まで一直線だし…

«Prev || 1 | 2 | 3 |...| 862 | 863 | 864 |...| 903 | 904 | 905 || Next»
Search
Feeds

Page Top