Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.c > #142705

[PC] Simulating Monads, Lambdas, Closures, and Laziness

Path csiph.com!eternal-september.org!feeder.eternal-september.org!reader01.eternal-september.org!.POSTED!not-for-mail
From M Joshua Ryan <luser.droog@gmail.com>
Newsgroups comp.lang.c
Subject [PC] Simulating Monads, Lambdas, Closures, and Laziness
Date Mon, 01 Apr 2019 16:26:56 -0500
Organization A noiseless patient Spider
Lines 156
Message-ID <vriumul9to0v.fsf@gmail.com> (permalink)
Mime-Version 1.0
Content-Type text/plain
Injection-Info reader02.eternal-september.org; posting-host="04752428d8d587c0742764048e25b0cf"; logging-data="6636"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX19IfqiIGCmq45t1Wm3VV31Rn7UMPGKcHTY="
User-Agent Gnus/5.13 (Gnus v5.13) Emacs/25.3 (cygwin)
Cancel-Lock sha1:PdSXjg9v08K+13AkBkYzm0ZVAv8= sha1:XmB9if/jflMh8hgu9t1y6II7sa8=
Xref csiph.com comp.lang.c:142705

Show key headers only | View raw


Norah is my computer's name.


#include <ctype.h>
#include <stdlib.h>
#include <stdio.h>

typedef union object *object;
typedef enum { INT, LIST, SUSP, PARSER, OPER } tag;
union object { tag t;
      struct { tag t; int i; } Int;
      struct { tag t; object a, b; } List;
      struct { tag t; void *v; object (*f)( void * ); } Susp;
      struct { tag t; void *v; object (*f)( void *, object ); } Parser;
      struct { tag t; void *v; object (*f)( void *, object ); } Oper;
};

object new_( union object o ){
  object p = calloc( 1, sizeof o );
  return  p ? *p = o, p : 0;
}
#define OBJECT(...) new_( (union object){ __VA_ARGS__ } )

object Int( int i ){               return  OBJECT( .Int    = { INT, i        } ); }
object one( object a ){            return  OBJECT( .List   = { LIST, a, NULL } ); }
object cons( object a, object b ){ return  OBJECT( .List   = { LIST, a, b    } ); }

object Susp( void *v, object (*f)( void * ) ){           return  OBJECT( .Susp   = { SUSP, v, f    } ); }
object Parser( void *v, object (*f)( void *, object ) ){ return  OBJECT( .Parser = { PARSER, v, f  } ); }
object Oper( void *v, object (*f)( void *, object ) ){   return  OBJECT( .Oper   = { OPER, v, f    } ); }

object at( object a ){ return  a && a->t == SUSP  ? at( a->Susp.f( a->Susp.v ) ) : a; }
object x( object a ){  return  a && a->t == LIST  ? a->List.a : NULL; }
object xs( object a ){ return  a && a->t == LIST  ? a->List.b = at( a->List.b ) : NULL; }

object parse( object p, object input ){
  return  p->t == PARSER  ? p->Parser.f( p->Parser.v, input ) : NULL;
}


object string_input( void *v ){
  char *p = v;
  return  *p  ? cons( Int( *p ), Susp( p+1, string_input ) ) : NULL;
}


object fresult( void *v, object input ){
  return  one( cons( v, input ) );
}
object result( object v ){
  return  Parser( v, fresult );
}


object fitem( void *v, object input ){
  return  input  ? one( cons( x( input ), xs( input ) ) ) : NULL;
}
object item( void ){
  return  Parser( 0, fitem );
}


object apply( object f, object o ){
  return  f->t == OPER  ? f->Oper.f( f->Oper.v, o ) : NULL;
}
object map( object f, object o ){
  return  o  ? cons( apply( f, x( o ) ), map( f, xs( o ) ) ) : NULL;
}
object last( object a ){
  return  a->List.b  ?  last( a->List.b ) : a;
}
object append( object a, object b ){
  return  a ? last( a )->List.b = b, a : b;
}
object join( object o ){
  return  o  ? append( x( o ), join( xs( o ) ) ) : NULL;
}
object fbind( void *v, object input ){
  object o = v;
  object p = x( o );
  object f = xs( o );
  return  join( map( f, parse( p, input ) ) );
}
object bind( object p, object f ){
  return  Parser( cons( p, f ), fbind );
}


int alpha( object o ){
  return isalpha( o->Int.i );
}
int digit( object o ){
  return isdigit( o->Int.i );
}
object fsat( void *v, object o ){
  int (*pred)( object ) = v;
  return  pred( x( o ) )  ? one( o ) : NULL;
}
object sat( int (*pred)( object ) ){
  return bind( item(), Oper( pred, fsat ) );
}
object is_alpha( void ){
  return  sat( alpha );
}
object is_digit( void ){
  return  sat( digit );
}


object seq( object p, object q ){
}

void print( object o ){
  if(  !o  ){ printf( "() " ); return; }
  switch( o->t ){
    case INT: printf( "%d ", o->Int.i ); break;
    case LIST: printf( "(" ); print( o->List.a ); print( o->List.b ); printf( ") " ); break;
    case SUSP: printf( "SUSP " ); break;
    default: break;
  }
}

int main(){
  char *s = "my string";
  object p = string_input( s );
  printf( "%c", x( p )->Int.i );
  printf( "%c", x( xs( p ) )->Int.i );
  printf( "%c", x( xs( xs( p ) ) )->Int.i );
  puts("");
  print( p ), puts("");
  object q = result( Int(42) );
  print( parse( q, p ) ), puts("");
  print( parse( item(), p ) ), puts("");
  print( parse( is_alpha(), p ) ), puts("");
  print( parse( is_digit(), p ) ), puts("");
}



]0;~/pcomb
Norah@laptop ~/pcomb
$ !m
make CFLAGS=-g pc7
cc -g    pc7.c   -o pc7
]0;~/pcomb
Norah@laptop ~/pcomb
$ ./pc7
my 
(109 (121 (32 SUSP ) ) ) 
((42 (109 (121 (32 SUSP ) ) ) ) () ) 
((109 (121 (32 SUSP ) ) ) () ) 
((109 (121 (32 SUSP ) ) ) () ) 
() 
]0;~/pcomb
Norah@laptop ~/pcomb
$ 

Back to comp.lang.c | Previous | Next — Next in thread | Find similar | Unroll thread


Thread

[PC] Simulating Monads, Lambdas, Closures, and Laziness M Joshua Ryan <luser.droog@gmail.com> - 2019-04-01 16:26 -0500
  Re: [PC] Simulating Monads, Lambdas, Closures, and Laziness Chad <cdalten@gmail.com> - 2019-04-01 14:42 -0700
    Re: [PC] Simulating Monads, Lambdas, Closures, and Laziness luser droog <luser.droog@gmail.com> - 2019-04-01 14:57 -0700
  Re: [PC] Simulating Monads, Lambdas, Closures, and Laziness Ben Bacarisse <ben.usenet@bsb.me.uk> - 2019-04-01 23:55 +0100
    Re: [PC] Simulating Monads, Lambdas, Closures, and Laziness luser droog <luser.droog@gmail.com> - 2019-04-02 00:31 -0700
      Re: [PC] Simulating Monads, Lambdas, Closures, and Laziness David Brown <david.brown@hesbynett.no> - 2019-04-02 10:25 +0200
        Re: [PC] Simulating Monads, Lambdas, Closures, and Laziness Manfred <noname@add.invalid> - 2019-04-02 14:11 +0200
          Re: [PC] Simulating Monads, Lambdas, Closures, and Laziness David Brown <david.brown@hesbynett.no> - 2019-04-02 15:51 +0200
      Re: [PC] Simulating Monads, Lambdas, Closures, and Laziness Ben Bacarisse <ben.usenet@bsb.me.uk> - 2019-04-02 12:10 +0100
      Re: [PC] Simulating Monads, Lambdas, Closures, and Laziness luser droog <luser.droog@gmail.com> - 2019-04-02 12:07 -0700
    Re: [PC] Simulating Monads, Lambdas, Closures, and Laziness Tim Rentsch <tr.17687@z991.linuxsc.com> - 2019-04-03 07:59 -0700
      Re: [PC] Simulating Monads, Lambdas, Closures, and Laziness Ben Bacarisse <ben.usenet@bsb.me.uk> - 2019-04-03 16:29 +0100
        Re: [PC] Simulating Monads, Lambdas, Closures, and Laziness Tim Rentsch <tr.17687@z991.linuxsc.com> - 2019-04-07 00:11 -0700
          Re: [PC] Simulating Monads, Lambdas, Closures, and Laziness luser droog <luser.droog@gmail.com> - 2019-04-12 23:20 -0700
            Re: [PC] Simulating Monads, Lambdas, Closures, and Laziness Chad <cdalten@gmail.com> - 2019-04-13 04:42 -0700

csiph-web