schemeのexpression datatypeの使い方について

このQ&Aのポイント
  • schemeのexpression datatypeを使って式を表現する方法について教えてください。
  • 特にexp->string関数について困っています。
  • consやifなどの関数を使うべきかどうかも教えてください。
回答を見る
  • ベストアンサー

schemeのことです

schemeのことです expression datatypeを作りました 一番最後のexp->string部分で困っています consとかifとか使うべきですか? -------------------------------- (define-datatype expression expression? (const-exp (num number?)) (var-exp (var symbol?)) (zero?-exp (exp1 expression?)) (diff-exp (exp1 expression?) (exp2 expression?))) ;; Predicates. (define const-exp? (lambda (exp) (cases expression exp (const-exp (num) #t) (else #f)))) (define var-exp? (lambda (exp) (cases expression exp (var-exp (var) #t) (else #f)))) (define zero?-exp? (lambda (exp) (cases expression exp (zero?-exp (exp1) #t) (else #f)))) (define diff-exp? (lambda (exp) (cases expression exp (diff-exp (exp1 exp2) #t) (else #f)))) ;; ====================================================================== ;; Extractors. (define exp->const (lambda (exp) (cases expression exp (const-exp (num) num) (else #f)))) (define exp->var (lambda (exp) (cases expression exp (var-exp (var) var) (else #f)))) (define exp->exp1 (lambda (exp) (cases expression exp (zero?-exp (exp1) exp1) (else #f)))) (define exp->exp2 (lambda (exp) (cases expression exp (diff-exp (exp1 exp2) exp2) ;; ====================================================================== ;; exp->string: exp -> string ;; Abstract syntax to concrete syntax. (define exp->string (lambda (exp) (cond ((const-exp? exp) (format "~a" (exp->const exp))) ((var-exp? exp) (format "~a" (exp->var exp))) ((zero?-exp? exp) (format "zero?(~a)" (exp->exp1 exp))) ((diff-exp? exp) (format "-(~a,~a)" (exp->exp2 exp)(exp->exp2 exp))) (else #f

質問者が選んだベストアンサー

  • ベストアンサー
回答No.1

全く要領を得ない質問ですね。 そもそも公式にはdefine-datatypeなんてマクロ(あるいは特殊形式)なんて定義されていない筈。 もうちょっと「何を目的にして何をやりたいのか」記述した方がいいと思いますね。

yawara18
質問者

補足

あ そうですか? 新しい言語を作ったんです それがexpression 内容の全部が定義です 最後にexpression言語をstring文字に変えるexp->stringを作ってますが

関連するQ&A

  • Schemeのプログラミング うるう年関連

    Schemeのプログラミング うるう年関連 Schemeで、 「(1)閏年かどうかを判定する関数leap?(number -> boolean)を定義した後、(2)○年○月の日数は何日かを求める関数num-of-days(number number -> number)を定義せよ」 という内容の課題を出されたのですが、(例えば 2009年の7月→31日 2012年の2月→29日) どうもエラーが出て実行できません。 自分は以下のように組みました。 ;;(1)の関数 (define (leap? year) (cond [(= (remainder year 400) 0) #t] [(and (= (remainder year 4) 0)(> (remainder year 100) 0)) #t] [else #f] ) ) ;;(2)の関数 (define (num-of-days year month) (cond [(and (= month 2)(= (leap? year) #t)) 29] [(and (= month 2)(= (leap? year) #f)) 28] [(or (= month 1)(= month 3)(= month 5) (= month 7)(= month 8)(= month 10) (= month 12)) 31] [else 30] ) ) これを例えば (num-of-days 2008 4) や (num-of-days 1995 12) などとして実行すると、それぞれ30,31という正しい値を返してくれるのですが、 (num-of-days 2008 2) や (num-of-days 1995 2) など、閏年・非閏年に関係無く、2月が絡むと =: expects type <number> as 1st argument, given: false; other arguments were: true というエラーを吐いてしまいます。 何度も見直しましたが、どこが間違っているのか見付けきれません…。どなたか間違いを指摘して頂けると幸いです。

  • scalaで無限に続く関数を返したい

    scalaで無限に続く関数を返したい scalaという物を知って現在弄り始めた初心者です。 例えばschemeでなら (define f (lambda () (define n (lambda (x) (display x) (display "\n") (lambda () (n (+ x 1))))) (n 0))) (((f))) こんな感じの事がしてみたいですが、これをそのまま下の様に書き換えたところ、コンパイルに失敗しました。 def f()={ def n(x:Int) = { println(x) () => n(x+1) } n(0) } def main(arg:Array[String])={ f()()() } これだと、コンパイラにnが何返すか分からんと怒られてしまいます。単純に返す物が分かっているときは :(()=>Int)= などと書いたら出来たのですが、今回は永遠に終わらないので書き方が分かりません。 どの様に返値を指定すればいいのでしょうか?

  • C言語の、戻り値/値渡し/アドレス渡しのついて

    【実装したコードに、戻り値/値渡し/アドレス渡しを用いたサブの関数を作成せよ。】 上記の課題に取り組んでいるのですが、何となく概念は分かったのですが、ソースコードに反映させようとすると詰まってしまって… どなたか教えて頂けないでしょうか? 『ソースコード』 #include <stdio.h> #include <time.h> #include <string.h> #include <stdlib.h> #define CALC (3) #define FROM_YEAR (1900) #define MAX_LINE (1000) int cmp_u(const void* a, const void* d) { return strcmp((char*)a, (char*)d); } int cmp_d(const void* a, const void* d) { return strcmp((char*)d, (char*)a); } int main() { int num1, num2; char op; float answer; int r,i; FILE* fp; char e[11]; char sin[1000][1000]; char ad[8]; fp = fopen("log.txt", "a+"); if (fp == NULL) { printf("ファイルオープン失敗\n"); return -1; } while (1) { r = scanf("%d%c%d", &num1,&op, &num2); if (r != CALC) { puts("input error"); return 1; } if (op == '+') { answer = num1 + num2; } else if (op == '-') { answer = num1 - num2; } else if (op == '*') { answer = num1 * num2; } else if (op == '/') { answer = (float)num1 / num2; } time_t t = time(NULL); struct tm* tm = localtime(&t); printf("%d/%02d/%02d ", tm->tm_year + FROM_YEAR, tm->tm_mon + 1, tm->tm_mday); printf("%02d:%02d:%02d ", tm->tm_hour, tm->tm_min, tm->tm_sec); printf("%d%c%d,%f\n", num1, op, num2, answer); fprintf(fp, "%d/%02d/%02d ", tm->tm_year + FROM_YEAR, tm->tm_mon + 1, tm->tm_mday); fprintf(fp, "%02d:%02d:%02d ", tm->tm_hour, tm->tm_min, tm->tm_sec); fprintf(fp, "%d%c%d,%f\n", num1, op, num2, answer); printf("計算を続けますか?"); scanf("%s", e); if (strcmp(e, "no") == 0) { break ; } } fclose(fp); fp = fopen("log.txt", "r"); int cnt = 0; for (i = 0;i < MAX_LINE;i = i + 1) { if (fgets(sin[i], sizeof(sin[0]), fp)) ++cnt; else break; } fclose(fp); printf("ASC or DESC: "); scanf("%s", ad); if (strcmp(ad, "ASC") == 0) { qsort(sin, cnt, sizeof(sin[0]), cmp_u); } else { qsort(sin, cnt, sizeof(sin[0]), cmp_d); } for (i = 0;i < cnt;i = i + 1) { printf("%s", sin[i]); } return 0; }

  • chromeでxmlをJSで表示するには?

    chromeだとエラーで表示できません。 どうすればいいのでしょうか? window.onload=function(){ Docm = new ActiveXObject('microsoft.XMLDOM'); Docm.async = false; Docm.load('xmlsrc'); var string = ""; if(Docm.documentElement.hasChildNodes()) { var i = 0; var n_num = Docm.documentElement.childNodes.length; while (i < n_num) { string += Docm.documentElement.childNodes.item(i).text += " "; i++; } } else { string +="子ノードはありません。"; } hyouji.innerHTML = string; }

  • Maximaで微分演算子

    知恵袋で聞いたらなぜか日本語が通じなかったので、okwaveにしました。 こっちならその都度捕捉できますし。 重複すいません。 数式処理システムMaximaで微分演算子を定義しようと思っています。 具体的には、1引数関数f(x)を受け取って、(例えば)x^2*f'(x)を返す関数d(f)を定義します。 理想的には、hoge(t):=sin(t);などとしたとき,d(hoge)(x)がx^2*cos(x)を返し、d(d(hoge))(p)がp^2*(2*p*cos(p)-p^2*sin(p))を返す、といった具合です。 素朴に思いつくのは、 d1(f,x):=x^2*diff(f(x),x); ですが、まずxも引数に取らねばならず、返り値が関数ではありません。 また、hoge(x):=sin(x);としてd1(hoge,5)などとすると、5^2*diff(sin(5),5)としてしまいます。 そこで、 d2(f,x):=subst(x,y,y^2*diff(f(y),y)); とすれば、先ほどの問題(d1(hoge,5))は解決しますが、やはり関数を返すのではなく値を返しています。 これだと、d2(d2(f,x),x)のようにできず、d2(lambda([x],d2(f,x)),x)としなければなりません。 d2(d2(d2(f)))とかだと、さらに面倒になります。 関数を返すために、lambdaを使って d3(f):=lambda([x],subst(x,y,y^2*diff(f(y),y))); としても、hoge(x):=sin(x);d3(hoge)(x)とすると、x^2*('diff(f(x),x,1))となります。 d1,d2については、うまくいかない理由は理解できるのですが、 d3についてはわかりません。 d3がうまくいかない理由と、当初の意図した関数はどうすれば実装できるのか、教えてください。 あと、n階微分ならdiff(f(x),x,n)とすれば良いですが、dをn回作用させる(つまり、d(d(...d(f)..))とする)にはどうすればよいでしょうか。やはり再帰しかないですかね。 Maximaの情報はググってもあまり出てこないので、誰か詳しい人、教えてください!

  • FLASHの出力エラーについて

    FLASHの出力エラーの原因がわかりません。 プレビューを押したとき ArgumentError: Error #2004: パラメータの 1 つが無効です。 at flash.display::Graphics/drawRect() at _fla::MainTimeline/xClick() とでてしまいます。 詳しい方、ご教授お願い致します。 ↓アクションスクリプトです add_btn.addEventListener(MouseEvent.CLICK, xClick); function xClick(evt) { var num1:Number = Number(in1_txt.text); var num2:Number = Number(in2_txt.text); var h:Number; if (num1 < 18) { h = 60; } else if ((num1 >= 18) && (num1 < 20)) { h = 50; } else if ((num1 >= 20) && (num1 < 23)){ h = 40; } var black:Number; if (num1 < 18) { black = (0xb0c4de); } else if ((num1 >= 18) && (num1 < 20)) { black = (0x8e9db2); } else if ((num1 >= 20) && (num1 < 23)) { black = (0x66707f); } else if ((num1 >= 23) && (num1 < 26)) { black = (0x232933); } else if(num1 > 25) { black = (0x232933); } var iro:Number; if (num1 < 18) { iro = 0.3;; } else if ((num1 >= 18) && (num1 < 20)) { iro = 0.4; } else if ((num1 >= 20) && (num1 < 23)){ iro = 0.5; }else if (num1 >50){ iro = 1.0; } var color:Number; if ((num2 >= 18) && (num2 <=25)){ color = (Math.random() * 0xffffff); } else if ( (num2 >=40) && (num2 <= 50)) { color = (0x999966); } else if(num1 > 50){ color = (0x996633); } else { color = (Math.random() * 0xffffff); } var k:Number; if ((num1 >= 23) && (num1 < 25)) { var mae:Shape=new Shape(); mae.graphics.beginFill(color); mae.alpha = 0.5; mae.graphics.drawRect(645 ,410, 310, 30); mae.graphics.endFill(); addChild(mae); for( y = 455 ; y <= 770 ; y = y + 255 ) { var ye:Shape=new Shape(); ye.graphics.beginFill(black); ye.graphics.drawRect(645 ,y, 310, 35); ye.graphics.endFill(); addChild(ye); } for( y = 505 ; y <= 700 ; y = y + 55 ) { var shima:Shape=new Shape(); shima.graphics.beginFill(color); shima.alpha = 0.5; shima.graphics.drawRect(645 ,y, 310, 28); shima.graphics.endFill(); addChild(shima); } } var m:Number; if (num1 >= 25) { var bod:Shape=new Shape(); bod.graphics.beginFill(color); bod.alpha = 0.5; bod.graphics.drawRect(645 ,410, 310, 10); bod.graphics.drawRect(645 ,490, 310, 10); bod.graphics.drawRect(645 ,660, 310, 20); bod.graphics.drawRect(645 ,685, 310, 5); bod.graphics.endFill(); addChild(bod); for( y = 430 ; y <= 700 ; y = y + 265 ) { var rec:Shape=new Shape(); rec.graphics.beginFill(black); rec.graphics.drawRect(645 ,y, 310, 50); rec.graphics.endFill(); addChild(rec); } for( y = 500 ; y <= 655 ; y = y + 40 ) { var ran:Shape=new Shape(); ran.graphics.beginFill(color); ran.alpha = 0.5; ran.graphics.drawRect(645 ,y, 310, Math.random()*30); ran.graphics.endFill(); addChild(ran); } }

  • 極小コードに挑戦!part2 数列を漢数字表記で!

    前回のカレンダーが 便利というわけではないが・・・ と思われてしまったので、実用的かもしれないお題で! もちろんアルゴリズムは問いません。 ○ 1111 千百十一  × 1111 一千一百一拾一 数列を漢数字表記に変換するコードを匠の技で見せてください!^^; 不可思議とかまでいっちゃってもOK! <html> <script> alert(kansuji('12345678901234')); function kansuji(num){ var k = ' 一 二 三 四 五 六 七 八 九'.split(' '); var t = ' 十 百 千'.split(' ') var u = ' 万 億 兆 京'.split(' '); var m = num.length; var r = ''; var c = 0; var f = 0; for(var i=0;i<m;i++){ n=num.substr(m-i-1,1); if(c>3) {c=0;t[0]=u[++f];} r=((c && n==1)?'':k[n])+t[c]+r; c++; } return r; } </script>

  • 基本的なC言語のプログラム

    C言語を勉強中です・・・ 0秒から1.0秒まで0.01秒刻みでデータ(s[i])を配列から表示させていく簡単なプログラムです。 0から0.2までは"30" 0.2から0.4までは"29" 0.4から1.0までは"30"と表示させたいのですが、 全て"30"と表示されてしまいます。 配列の仕方が悪いのでしょうか?? すごく基本的な質問かもしれませんが、どなたか分かる方、よろしくお願いします。 #include <stdio.h> #include <math.h> #define number0 (100) #define h (0.01) #define f1 (30.0) #define f2 (29.0) void main(void){ double s[number0]={0}; int i; double t; for(i=0; i<number0; i++){ t=h*i; if(0<=i<20){ s[i]=f1; } else { if (20<=i<40){ s[i]=f2; } else { s[i]=f1; } } printf("%g %g\n",t,s[i]); } }

  • C言語のqsortについて

    現在、qsortのコードに取り組んでいます。 if (strcmp(ad, "ASC") == 0) { qsort(sin, sizeof(cnt), sizeof(sin[0]), cmp_u); } else { qsort(sin, sizeof(cnt), sizeof(sin[0]), cmp_d); } 恐らくこちらのqsortでの第二引数が書き方を間違えていると思うのですが、修正の方法が分からず、どなたか教えて頂けないでしょうか? #include <stdio.h> #include <time.h> #include <string.h> #include <stdlib.h> static char ad[10]; int cmp_u(const void* a, const void* d) { return strcmp((char*)a, (char*)d); } int cmp_d(const void* a, const void* d) { return strcmp((char*)d, (char*)a); } int main() { int num1, num2; char op; float answer; int r,i; FILE* fp; char c[11]; char sin[1000][1000]; char ad[8]; fp = fopen("log.txt", "a+"); if (fp == NULL) { printf("ファイルオープン失敗\n"); return -1; } while (1) { r = scanf("%d%c%d", &num1, &op, &num2); if (r != 3) { puts("input error"); return 1; } if (op == '+') { answer = num1 + num2; } else if (op == '-') { answer = num1 - num2; } else if (op == '*') { answer = num1 * num2; } else if (op == '/') { answer = (float)num1 / num2; } time_t t = time(NULL); struct tm* tm = localtime(&t); printf("%d/%02d/%02d ", tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday); printf("%02d:%02d:%02d ", tm->tm_hour, tm->tm_min, tm->tm_sec); printf("%d%c%d,%f\n", num1, op, num2, answer); fprintf(fp, "%d/%02d/%02d ", tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday); fprintf(fp, "%02d:%02d:%02d ", tm->tm_hour, tm->tm_min, tm->tm_sec); fprintf(fp, "%d%c%d,%f\n", num1, op, num2, answer); printf("計算を続けますか?"); scanf("%s\n", &c); if (strcmp(c, "no") == 0) { break ; } } fclose(fp); fp = fopen("log.txt", "r"); int cnt = 0; for (i = 0;i < 1000;i = i + 1) { if (fgets(sin[i], sizeof(sin[0]), fp)) ++cnt; else break; } fclose(fp); printf("ASC or DESC: "); scanf("%s", ad); if (strcmp(ad, "ASC") == 0) { qsort(sin, sizeof(cnt), sizeof(sin[0]), cmp_u); } else { qsort(sin, sizeof(cnt), sizeof(sin[0]), cmp_d); } for (i = 0;i < cnt;i = i + 1) { printf("%s", sin[i]); } return 0; }

  • exp()が計算されなくて困ってます。

    #include <stdio.h> #include <math.h> #define C_B 13.5e-12 #define C_D 5.5e-12 #define R 100 #define Vb 3e3 /* Breakdown voltage [V]*/ #define Vpp 8e3 #define f 50e3 void main(void){ double C,t=0.0; double dt,tmax,i=0,v=0,bv=0,vc1=0,vc2=0,q1=0,q2=0,w=0,CR; FILE *fp; fp=fopen("test4.txt","w"); C=(C_B*C_D)/(C_B+C_D); tmax=(1/f)*2; dt=tmax/1000; w=2*3.14*f; CR=-1/(R*C_B); while(1){  if(fabs(v-vc2)>=Vb/2){   while(1){    v=(Vpp/2)*sin(w*t);    if(fabs(v-vc2)>=0.1*(Vb/2)){     i=(Vpp/2)*(C_B*w/(pow(R,2)*pow(C_B,2)*pow(w,2)-1))*(R*C_B*w*sin(w*t)-exp(CR*t)+cos(w*t)); この式で使われているexpです。↑ q1=q1+i*dt; q2=q2+i*dt; vc1=i/R; vc2=q2/C_B; } else{break;} fprintf(fp,"%1.10f %1.10f %1.10f %1.10f % 1.10f\n",t,v,i,vc2,q2); t=t+dt; if(t>=tmax)break; } } else{ while(1){ v=(Vpp/2)*sin(w*t); i=C*(v-bv)/dt; q2=q2+i*dt; q1=q1+i*dt; vc1=q1/C_D; vc2=q2/C_B; fprintf(fp,"%1.10f %1.10f %1.10f %1.10f\n",t,v,i,vc2,q2); bv=v; t=t+dt; if(fabs(v-vc2)>=Vb/2)break; if(t>=tmax)break; } } if(t>=tmax)break; } fclose( fp ); } この問題を解決できる人がいたら教えてください。

専門家に質問してみよう