可変長引数を使ったfoldl(言語によってはreduceとも言う)もどきを作ることで実現してみました。
C
1 # include <stdio.h>
2 # include <stdarg.h>
3
4 int kisoku ( int accs , void * data ) ;
5 int foldl ( int ( * func ) ( int , void * ) , int accs , int count , . . . ) ;
6 int vfoldl ( int ( * func ) ( int , void * ) , int accs , int count , va_list list ) ;
7
8 int main ( void )
9 {
10 int a , b , c , d , e , f , g , h , i , j , k , l ;
11 // kisokuが規則。0は初期値。foldlで左畳み込み
12 foldl ( kisoku , 0 , 12 , & a , & b , & c , & d , & e , & f , & g , & h , & i , & j , & k , & l ) ;
13 printf ( "l = %d\n" , l ) ;
14 return 0 ;
15 }
16
17 // 実際の規則
18 int kisoku ( int accs , void * data )
19 {
20 int * i = ( int * ) data ;
21 * i = accs + 2 ;
22 return * i ;
23 }
24
25 /* Haskellでのfoldl(左畳み込み)もどきをCで実現(ただし、int専用)
26 foldl :: (a -> b -> a) -> a -> [b] -> a
27 foldl f a [] = a
28 foldl f a (x:xs) = foldl f (f a x) xs
29 ※ aはint、[b]は[void*]だけど、配列では無く可変長引数なので残数付き。
30 */
31 int foldl ( int ( * func ) ( int , void * ) , int accs , int count , . . . )
32 {
33 va_list list ;
34 va_start ( list , count ) ;
35 accs = vfoldl ( func , accs , count , list ) ;
36 va_end ( list ) ;
37 return accs ;
38 }
39
40 int vfoldl ( int ( * func ) ( int , void * ) , int accs , int count , va_list list )
41 {
42 if ( count == 0 ) {
43 return accs ;
44 } else {
45 // 末尾呼出し最適化してくれるかもしれない。
46 return vfoldl ( func , func ( accs , va_arg ( list , void * ) ) , -- count , list ) ;
47 }
48 }
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。