Itu hampir Gila!

14

Tantangan

Tantangan Anda adalah merancang juru bahasa untuk bahasa mirip lisp , yang sejak saat itu akan diciptakan: GLisp . Kode program untuk GLisp akan terdiri dari jumlah ekspresi bersarang yang ditunjukkan oleh tanda kurung, dalam bentuk berikut:

(func arg1 arg2 ...)

Perhatikan bahwa interpreter harus mengizinkan karakter spasi kosong sebelum dan sesudah tanda kurung, fungsi, dan argumen.

Jenis

Anda akan menerapkan empat jenis, Integer, Daftar, Boolean, dan Fungsi. Nilai integer dan Boolean dapat secara eksplisit dimasukkan ke dalam kode sumber dengan sintaks mereka sendiri. Penerjemah Anda harus mengasumsikan bahwa sejumlah karakter numerik menunjukkan Integer (Anda tidak harus menerapkan sintaks untuk secara eksplisit memasukkan bilangan bulat negatif). Penerjemah Anda juga harus mengasumsikan bahwa truedan falsediberi nilai Boolean. Fungsi tidak dapat didefinisikan secara eksplisit oleh pengguna, dan akan selalu mengembalikan nilai tunggal (Daftar panjang apa pun dianggap sebagai nilai tunggal).

Fungsi

Fungsi-fungsi berikut harus diimplementasikan, dan berada dalam format Function , Arity . Jika Arity ndiproses oleh tanda plus, maka itu menunjukkan natau lebih banyak argumen. Anda dapat mengasumsikan bahwa semua argumen yang diberikan untuk suatu fungsi adalah dari jenis yang sama, kecuali dinyatakan sebaliknya. Anda juga dapat mengasumsikan bahwa jika tidak ada perilaku yang ditentukan untuk tipe certian, maka Anda dapat mengasumsikan bahwa tidak ada argumen fungsi yang akan menjadi tipe itu. Argumen akan disebut sebagai dalam diagram berikut:

(func argument1 argument2 ... argumentn)

  • + , 2+

    • Jika semua argumen bertipe Integer , Anda harus mengembalikan jumlah argumen
    • Jika semua argumen bertipe List , Anda harus mengembalikan rangkaian argumen dalam urutan menaik ( arg1+arg2+ ...)
    • Jika semua argumen bertipe Boolean , Anda harus mengembalikan logis Semua urutan argumen
    • (+ 1 2 3 4 5) -> 15
    • (+ (list 1 2) (list 3 4)) -> (list 1 2 3 4)
    • (+ true true true) -> true
  • - , 2+

    • Jika semua argumen bertipe Integer , Anda harus mengembalikan perbedaan argumen ( arg1-arg2- ...)
    • Jika semua argumen bertipe Boolean , Anda harus mengembalikan logika Apa pun dari urutan argumen
    • (- 8 4 3) -> 1
    • (- 0 123) -> -123
    • (- true false false true false) -> true
  • * , 2+

    • Jika semua argumen bertipe Integer , Anda harus mengembalikan produk dari argumen tersebut
    • Jika satu argumen bertipe Daftar dan yang lainnya bertipe Integer (Anda dapat mengasumsikan bahwa ini hanya akan menjadi satu-satunya argumen yang diberikan), Anda harus mengembalikan Daftar baru dengan item dalam waktu yang arg1berulang arg2.
    • (* 1 2 3 4 5) -> 120
    • (* (list 1 2 3) 2) -> (list 1 2 3 1 2 3)
  • / , 2+

    • Jika semua argumen bertipe Integer , Anda harus mengembalikan hasil bagi argumen ( arg/arg2/ ...) (Anda dapat mengasumsikan bahwa pembagian dilakukan secara berurutan, dan bahwa bagian desimal pada setiap langkah terpotong)
    • Jika satu argumen bertipe Daftar dan yang lainnya bertipe Function , maka Anda harus mengembalikan Daftar yang dihasilkan setelah arg2dipetakan pada setiap nilai
    • (/ 100 10 3) -> 3
    • (/ (list 1 2 3) inc) -> (list 2 3 4)
  • % , 2

    • Jika semua argumen bertipe Integer , Anda harus mengembalikan modulus argumen
    • (% 4 2) -> 0
  • = , 2+

    • Jika kedua jenis dan nilai semua argumen adalah sama, Anda harus kembali benar. Jika tidak, kembalikan salah.
    • (= 0 0 0) -> true
    • (= 0 false (list)) -> false
  • daftar , 0+

    • Anda harus mengembalikan daftar semua argumen, apa pun jenisnya. Jika tidak ada argumen yang diberikan, maka Anda harus mengembalikan daftar kosong
    • (list 3 4 (list 5)) -> (list 3 4 (list 5))
  • inc , 1

    • Jika argumen bertipe Integer , Anda harus mengembalikan Integer yang bertambah satu
    • Jika argumen adalah tipe List , Anda harus mengembalikan List yang diputar searah jarum jam satu putaran
    • (inc 1) -> 2
    • (inc (list 1 2 3)) -> (list 3 1 2)
  • Desember , 1

    • Jika argumen bertipe Integer , Anda harus mengembalikan Integer yang dikurangi satu
    • Jika argumen adalah tipe List , Anda harus mengembalikan List yang diputar berlawanan arah jarum jam satu putaran
    • (dec 1) -> 0
    • (dec (list 1 2 3)) -> (list 2 3 1)
  • jika , 3

    • Jika diberi tiga argumen jenis apa pun: Jika nilai kebenarannya arg1benar, kembalikan arg2, kembalikan lagiarg3
    • (if (not (list 1)) 8 false) -> false
  • tidak , 1

    • Jika diberi argumen jenis apa pun, jika nilai kebenarannya arg1False, kembalikan true, kembalikan lagi false.
    • (not (list)) -> true
  • len , 1

    • Jika diberi argumen tipe daftar , kembalikan panjangarg1
    • (len (list 4 2 true (list 3) (list))) -> 5

Tabel kebenaran :, di 0, (list), false -> falsemana (list)menunjukkan daftar kosong. Yang lainnya adalah true.

Penerjemah Anda dapat berupa program lengkap yang membaca input sumber dari stdin atau file, atau fungsi yang mengambil sumber sebagai string dan mengembalikan nilai output.

Jika memilih yang pertama, output untuk Integer hanyalah angka, untuk Boolean adalah trueatau false, dan untuk daftar adalah urutan nilai-nilai yang dipisahkan spasi dalam tanda kurung (mis. (1 2 3 4 (5 6 7))Menunjukkan (list 1 2 3 4 (list 5 6 7))).

Jika memilih yang terakhir, nilainya harus dikembalikan dalam tipe yang sesuai bahasa implementasi, atau, jika tidak ada tipe yang serupa, tipe kustom. Daftar dapat dikembalikan sebagai Array atau Vektor jika bahasa tidak memiliki jenis Daftar , Boolean harus dikembalikan sebagai jenis Boolean dalam bahasa, atau jenis khusus jika bahasa tidak mendukung mereka.

Uji kasus

(list 1 2 3 (list 4 5 true))  -> (1 2 3 (4 5 true))
(/ 4000 (+ 1 2 3 4 (* 5 8)))  -> 80
(+ (not (- (len (list 5 6 7)) (/ 10 3))) true)  -> true
(if (           len (list )  ) 4 (if    (+ (= 8 8    8) (not (list 4))) 8 5))  -> 5

Klarifikasi

  • Penerjemah Anda mungkin berurusan dengan input yang tidak valid dengan cara apa pun yang Anda pilih, tetapi itu tidak boleh membuang pengecualian (meskipun, ia dapat mencetak pesan kesalahan dan keluar dengan lancar)
  • Fungsi akan selalu mengevaluasi argumen dari kiri ke kanan
  • Input yang tidak valid adalah setiap input yang secara sintaksis salah. Ini termasuk, tetapi tidak terbatas pada, tanda kurung yang tidak cocok, pembagian dengan nol, dan fungsi yang diterapkan sebagian (kecuali berlaku untuk bonus)
  • Karena =, jika ada nilai yang berbeda atau tipe yang berbeda, kembalikanfalse

Bonus

  • Nilai * 0,8 jika Anda mendukung fungsi yang diterapkan sebagian. Misalnya, ((+ 2) 3)akan sama dengan (+ 2 3), tetapi memungkinkan untuk hal-hal seperti (/ (list 1 2 3) (+ 2)). Anda dapat mengasumsikan bahwa suatu fungsi diterapkan sebagian jika menerima kurang dari jumlah minimum argumen
  • Nilai * 0,85 jika Anda tidak mengevaluasi argumen yang diterapkan ifkecuali mereka akan dikembalikan

Ini adalah kode-golf, jadi penerjemah dengan jumlah byte terendah menang!

globby
sumber
Bagaimana cara menafsirkannya (if (not (array 1)) 8 false) -> false?
feersum
@feersum tangkapan bagus, seharusnya 8.
globby
1
Bagaimana seharusnya kita mengevaluasi (+ 3 (if false 5))? Secara umum, apa yang sebenarnya "tidak mengembalikan apa-apa"? Anda tidak menentukan tipe unit apa pun yang akan
dibayar
3
1. Mengapa (+ bool bool...)logis DAN dan (- bool bool...)logis ATAU? Notasi dering standar akan digunakan +untuk OR dan *untuk AND. 2. Apakah "input tidak valid" dimaksudkan untuk mencakup kasus-kasus seperti (/ 2 0)mana yang secara sintaksis benar? 3. Karena =, jika nilainya tidak semuanya sama, haruskah itu dikembalikan false? 4. Definisi nottampaknya mundur. 5. Apa tokennya? Anda mengatakan bahwa penerjemah harus menangani spasi tambahan, tetapi Anda tidak mengatakan spasi apa yang bisa diandalkan. Untuk pertanyaan kompleks seperti ini, Anda harus menggunakan kotak pasir agar spek dapat diperiksa.
Peter Taylor
1
tidak jelas bagaimana aplikasi parsial harus bekerja: ((+ 2 3) 4)sama dengan 9atau kesalahan? Khususnya, untuk fungsi var-arg, tidak jelas kapan seseorang harus mempertimbangkan aplikasi parsial. Itu menjadi lebih kacau dengan hal-hal seperti((if true (+ 2 3) (- 5)) 4)
MtnViewMark

Jawaban:

6

Haskell, 1370 1263 1179 1128 1163 1107 1084 bytes * 0.8 * 0.85 = 737.12

import Text.Parsec
data V=I Int|L[V]|T|F|P[V]|X|A|S|M|D|U|E|Q|J|K|C|N|W deriving Eq
m Q=0;m C=3;m f|f`elem`[J,K,N,W]=1;m _=2
l=length
x v=[n|I n<-v]
y v=[l|L l<-v]
z v=[0<1|T<-v]++[1<0|F<-v]
(&)f=l.f>>=(.l).(==)
b a|a=T|0<1=F
s(I n)=show n
s(L v)='(':tail(v>>=(' ':).s)++")"
s T=d!!0;s F=d!!1;s _="error"
i(L v)=e$i%v
i v=v
e(P v:a)=e$v++a
e(f:a)|m f>l a=P(f:a)
e(A:a)|x&a=I$sum$x a|y&a=L$concat$y a|z&a=b$and$z a
e(S:a)|x&a=I$f$x a|z&a=b$or$z a
e(M:a)|x&a=I$product$x a
e[M,v,I n]=e$A:replicate n v
e(D:a)|x&a=I$v$x a
e[D,L v,f]=L$map(\a->e[f,a])v
e[U,I a,I b]=I$a`mod`b
e(E:a:v)=b$all(==a)v
e(Q:a)=L a
e[J,I a]=I$a+1
e[J,L[]]=L[]
e[J,L v]=L$last v:init v
e[K,I a]=I$a-1
e[K,L v]=L$drop 1 v++take 1 v
e[C,a,b,c]|a`elem`[I 0,L[],F]=c|0<1=b
e[N,a]=e[C,a,F,T]
e[W,L v]=I$l v
e _=X
f(a:b)=a-sum b
v(a:b)=foldl div a b
(%)f=fmap f
p=k$choice$try%([(I .read)%many1 digit,L%between(w"(")(k$w")")(many$try p)]++zipWith((.return).(>>).w)d[T,F,A,S,M,D,U,E,Q,J,K,C,N,W])
k=(spaces>>)
w=string
d=words"true false + - * / % = list inc dec if not len"
g=either show(s.i).parse p""
main=interact g

Program lengkap, membaca stdindan menulis untuk stdout. gadalah versi fungsi, juga.

Menerapkan fungsi parsial, dan evaluasi malas if.

Contoh dijalankan (dari versi fungsi):

λ: g "(list 1 2 3 (list 4 5 true))"
(1 2 3 (4 5 true))

λ: g "(/ 4000 (+ 1 2 3 4 (* 5 8)))"
80

λ: g "(+ (not (- (len (list 5 6 7)) (/ 10 3))) true)"
true

λ: g "(if (           len (list )  ) 4 (if    (+ (= 8 8    8) (not (list 4))) 8 5))"
5

λ: g "(if false (/ 1 0) 5)"
5

λ: g "((+ 2) 3)"
5

λ: g "(/ (list 1 2 3) (+ 2))"
(3 4 5)

Sekarang miliki semua unit test dari deskripsi:

λ: runTests 
passed: g "(+ 1 2 3 4 5)" ==> 15
passed: g "(+ (list 1 2) (list 3 4))" ==> (1 2 3 4)
passed: g "(+ true true true)" ==> true
passed: g "(- 8 4 3)" ==> 1
passed: g "(- 0 123)" ==> -123
passed: g "(- true false false true false)" ==> true
passed: g "(* 1 2 3 4 5)" ==> 120
passed: g "(* (list 1 2 3) 2)" ==> (1 2 3 1 2 3)
passed: g "(/ 100 10 3)" ==> 3
passed: g "(/ (list 1 2 3) inc)" ==> (2 3 4)
passed: g "(% 4 2)" ==> 0
passed: g "(= 0 0 0)" ==> true
passed: g "(= 0 false (list))" ==> false
passed: g "(list 3 4 (list 5))" ==> (3 4 (5))
passed: g "(inc 1)" ==> 2
passed: g "(inc (list 1 2 3))" ==> (3 1 2)
passed: g "(dec 1)" ==> 0
passed: g "(dec (list 1 2 3))" ==> (2 3 1)
passed: g "(if (not (list 1)) 8 9)" ==> 9
passed: g "(not (list))" ==> true
passed: g "(len (list 4 2 true (list 3) (list)))" ==> 5
passed: g "(list 1 2 3 (list 4 5 true))" ==> (1 2 3 (4 5 true))
passed: g "(/ 4000 (+ 1 2 3 4 (* 5 8)))" ==> 80
passed: g "(+ (not (- (len (list 5 6 7)) (/ 10 3))) true)" ==> true
passed: g "(if (           len (list )  ) 4 (if    (+ (= 8 8    8) (not (list 4))) 8 5))" ==> 5
passed: g "(if false (/ 1 0) 5)" ==> 5
passed: g "((+ 2) 3)" ==> 5
passed: g "(/ (list 1 2 3) (+ 2))" ==> (3 4 5)
MtnViewMark
sumber
b case e[K,L _]yang dapat Anda gunakan drop 1 sebagai versi aman taildan gunakan takeuntuk versi aman headbergabung dengan dua definisie[K,L _]
haskeller bangga
Anda dapat menggunakan fungsi notElem.another tip: Anda dapat melakukannya s=stringdan menggunakannya sebagai ganti keduanya stringdan char( s"C"vs. char 'C'). tip lain: gunakan penjaga bukannya ifs
bangga haskeller
Hal lain yang saya pikirkan: Anda dapat menyandikan Maybenilai berdasarkan daftar. Nothingadalah []dan Just xsekarang [x]. Ini menghilangkan konstruktor yang panjang dan menambahkan beberapa fungsi lagi: if p then Just x else Nothingadalah [x|p], (==Nothing)adalah null, daftar monad menjadi sama dengan mungkin monad, dan sebagainya.
haskeller bangga
@proudhaskeller Terima kasih, semua berlaku!
MtnViewMark
4

Python 2, 1417 * 0.8 * 0.85 = 963.56

from operator import*
A=type;K="list"
def E():print"E";exit()
def R(G):
 len(G)or E();T=G.pop(0);L=[]
 if"("==T:
  G or E()
  while")"!=G[0]:L+=[R(G)];G or E()
  G.pop(0);return L
 if")"==T:E()
 try:
  x=eval(T.title())
  if Q(x)<2:return x
  E()
 except:return T
H="+ - * / = % if inc dec not len"
Z=lambda y:lambda x:reduce(y,x)
D=dict(zip(H.split(),[[sum,any,0,lambda x:sum((y[1:]for y in x),[K])],[Z(sub)],[Z(mul),all,0,lambda x:x[0][:1]+x[0][1:]*x[1]],[Z(div),lambda x:[K]+map(lambda z:S([x[1],z]if Q(x[1])==2else x[1]+[z]),x[0][1:])],[lambda x:len(set(map(str,x)))<2]*6,[lambda x:x[0]%x[1]],[lambda x:S(x[2])if S(x[0])in[0,[K]]else S(x[1])]*6,[lambda x:x[0]+1,0,0,lambda x:x[0][:1]+x[0][-1:]+x[0][1:-1]],[lambda x:x[0]-1,0,0,lambda x:x[0][:1]+x[0][2:]+[x[0][1]]],[lambda x:x[0]in[0,[K]]]*6,[0]*3+[lambda x:len(x)-1]]))
H=H[:15]+H+" if"
def Q(x):
 t=A(x);w=int,bool,str
 if t in w:return w.index(t)
 if t==list and x:return 5-(2*(x[0]==K)+(str==A(x[0])and len(x)<H.count(x[0])+1))
 E()
def S(G):
 if Q(G)<2:return G
 G or E();c=G[0];r=G[1:];c==K or r or E()
 if c!="if":r=[x if Q(x)in{2,4}else S(x)for x in r]
 if c==K:return[c]+r
 k=map(Q,r);m=min(k);M=max(k);v=[m,[-1,3][{m,M}=={4,5}]][m!=M]
 try:return D[c][v](r)
 except:E()
def C(x):return"(%s)"%" ".join(map(C,x))if A(x)==list else str(x).lower()
def I(G):
 for c in"+-*/%=()":G=G.replace(c," %s "%c)
 return C(S(R(G.strip().split())))
print I(raw_input())

Perombakan total. Jika Anda ingin melihat versi sebelumnya, lihat riwayat edit .

Ada banyak lagi yang bisa dimainkan. Perlahan aku mengerjakannya.

Dengan zlib / base64 kita mendapatkan 1093 * 0.8 * 0.85 = 743.24 :

import base64,zlib
exec zlib.decompress(base64.b64decode("eJx9VE1P4zAQvedXGEuV7MbttgX2kOADAtSugANbTljWKqSuNku+5Lg0BfHfd8ZJCwjt9tLpdN6bmTczXtuqIFVtbOIqS7KirqwbBufS7WoTX0uaZ42jwcqsyRXjUW2z0tErGps2c4x7/08251FAclOCARwQF9/L+biuajbh8Y1UOiDZmjIq5T0EkjnposDc/s5yQzk9knM10dFNKBXS6fhDzIHJGrexJbnxbNyz+Qhnd0jbSvOc5Ox+7DKXG8YRm63JHWv52SzqwS04Pci0qand3n0fLCQNyYgMyTciyQCBWZmSlUlJWTlsjgYPMk+Kx1VCdlFvtIBfbVLDdqLlwaVcZaljL1nNFuOmzlEhoVSzKURS7sREHFDgYmynppFeQ5s7SEVaCL3WXAv1wJrNY2cUm5yLJM8/YlsQSkVTHXoDKIatmmofvsqe+Xsg0IVFUrPe8RItmcJQ8aI7WcDmUs5M3hiCP0L1ornY02IFBy4cbmMcQ77GWeiWg6h6+P1DDAIHfS0H5xLSzDSHhGhNwCrVBDvVPu2yq+IrUTiFnv/Z9Qjq2/c/+pwQvaP/gmeAVR1Yf4EeyvMlTfTwOPysQssxISzXQi6A81SHi5DiQvpbwGWDXXTyHIx4K+FaxGNV5QJEw7UlDme93a/ddpyVK9Myx7s/pcRzI0m58qvlY05HbDb02kl5zUOUXyI9iomBXVFni3FabUrX+cMpbv9Vf6DL7kD90OcfbmEeHE4xTv0Bxha+QFv4Ka/xL3s4Q0CnR5JCo5GVqt1fVla+zsTJ236YHPe5xR6t7jBA1OdTqQ5BhCeJS3QnLI8LWWQle+LxLfhaNJ6lKgSMVxxr9VqI2zcpX0/E6ZvWqjiSt7o79r7+S2BUz5rZ93Pet3yBc+jCKBs0nA4ooeM/FaTD7Be4wFAdTqnX3HcA2oJnnFdbY3umH5142FcKfdFwNPw2kIzTaA5vnDV1nsD9p4KSQUPoIIVa+vIu2JLBYzYGUngR+P5FgE/gn1Ggtsn2V1bWG3T/BUW+qRU="))

Catatan: Jika Anda melihat skor saya naik, itu mungkin karena saya menemukan beberapa bug

Sp3000
sumber
lebih banyak tantangan kode daripada kode golf tapi tetap saja, 4872 * 0.8 = 3897,6
Def
3

Common Lisp, 868 bytes * 0.85 = 737.8

Apakah curang menerapkan Lisp dengan Lisp? Masih banyak yang harus dioptimalkan di sini.

(SETF (READTABLE-CASE *READTABLE*) :PRESERVE)(PRINC(LABELS((B(X)(FIND X'(true false)))(R(X)(IF X'true'false))(V(X)(MEMBER X'(0()false)))(A(&REST X)(R(NOTANY #'V X)))(O(&REST X)(R(NOTEVERY #'V X)))(E(X &KEY N)(IF(LISTP X)(ECASE(FIRST X)(+(APPLY(IF(EVERY'NUMBERP #1=(MAPCAR(IF N #'IDENTITY #'E)(CDR X)))'+(IF(EVERY'LISTP #1#)'APPEND #'A))#1#))(-(APPLY(IF(EVERY'NUMBERP #1#)'- #'O)#1#))(*(IF(LISTP #2=(CAR #1#))(LOOP FOR I TO(1-(CADR #1#))APPEND #2#)(APPLY'* #1#)))(/(IF(LISTP #2#)(LOOP FOR I IN #2#COLLECT(E `(,(CADR #1#),I):N T))(REDUCE'FLOOR #1#)))(%(APPLY'MOD #1#))(=(R(LOOP FOR I IN(CDR #1#)ALWAYS(EQUAL I #2#))))(list #1#)(inc(IF(LISTP #2#)(APPEND(LAST #2#)(BUTLAST #2#))(1+ #2#)))(dec(IF(LISTP #2#)(APPEND(CDR #2#)`(,(FIRST #2#)))(1- #2#)))(if(IF(V(E(CADR X)))(E(CADDDR X))(E(CADDR X))))(not(R(V #2#)))(len(LENGTH #2#)))X)))(OR(IGNORE-ERRORS(OR(E(READ))"()")):E))

Mencetak E jika terjadi kesalahan input. Sampel berjalan:

$ sbcl --script glisp.lisp
(list 1 2 3 (list 4 5 true))
(1 2 3 (4 5 true))

$ sbcl --script glisp.lisp
(/ 4000 (+ 1 2 3 4 (* 5 8)))
80

$ sbcl --script glisp.lisp
(+ (not (- (len (list 5 6 7)) (/ 10 3))) true)
true

$ sbcl --script glisp.lisp
(if (           len (list )  ) 4 (if    (+ (= 8 8    8) (not (list 4))) 8 5))
5

$ sbcl --script glisp.lisp
(this is an error)
E

$ sbcl --script glisp.lisp
(if (% 4 2) (this is an error) 42)
42
jlahd
sumber
2
selama itu bukan semacam fungsi eval ...
Def
2

Haskell, 972

r=fst.f
f('(':s)|(f:a,b)<-g s=(f%filter(/="")a,b)
f s=span(`notElem`" ()")s
j=dropWhile(==' ')
g""=([],"")
g s|')':l<-r=([x],l)|(y,t)<-g$j r=(x:y,t)where(x,r)=f$j s
"%"%c=show$foldr(mod.read)(maxBound::Int)c
"+"%c|t(c!!0)<1="(list "++tail(c>>=(' ':).drop 6.init)++")"|t(c!!0)<2=show$sum$map read c|0<1=i$all((=='t').head)c
"-"%c|t(c!!0)<2=show$foldl1(-)$map read c|0<1=i$any((=='t').head)c
"*"%c=fst$f$"(+ "++unwords([1..read$last c]>>init c)++")"
"="%c=i$all(==c!!0)c
"/"%c|t(c!!0)<1,[a,b]<-c="list"%map(\x->b%[x])(fst$g$drop 6 a)|0<1=show$foldl1 div$map read c
"if"%[p,a,b]|elem p["0","()","false"]=b|0<1=a
"list"%c="(list "++unwords c++")"
"len"%[c]=show$length(words c)-1
"inc"%[c]|t c>0=show$read c+1|([],_)<-g$drop 6 c="(list)"|(x,_)<-g$drop 6 c="list"%(last x:init x)
"dec"%[c]|t c<1,(x,_)<-g$drop 6 c="list"%(drop 1 x++take 1 x)|0<1=show$read c-1
"not"%[c]="if"%[c,"false","true"]
s%c="?"
i p|p="true"|0<1="false"
t('(':_)=0
t(c:s)|c<':',c>'/'=1|elem c"th"=2
t _=3

solusi yang cukup meretas. ini menyimpan segala sesuatu sebagai string dalam bentuk siap-keluaran - tipe mereka dapat dibedakan dengan huruf pertama mereka - 0..9untuk angka, (untuk daftar, tatau funtuk boolean, dan segala sesuatu lainnya untuk fungsi.

untuk menjalankan gunakan rfungsi.

haskeller bangga
sumber