我正在使用messenger api from facebook,使用ningle。有在我的計劃了一下,我需要這個ALIST從jonathan來上班:使用泛型序列系統與lisp共同lisp與alist來自jonathan
CL-USER> (defparameter *params*
'(("entry"
(("messaging"
(("message" ("text" . "hola") ("seq" . 3227)
("mid" . "mid.$cAAGvLYgmIaVihhT_EFcVM-1tP17u"))
("timestamp" . 1496071517968)
("recipient" ("id" . "474086316315717"))
("sender" ("id" . "1695095647186162"))))
("time" . 1496071518212) ("id" . "474086316315717")))
("object" . "page")))
*PARAMS*
CL-USER> (length *params*)
2
然後,我有與入門部分工作:
CL-USER> (defparameter entries (cdr (assoc "entry" *params* :test #'string=)))
ENTRIES
CL-USER> entries
((("messaging"
(("message" ("text" . "hola") ("seq" . 3227)
("mid" . "mid.$cAAGvLYgmIaVihhT_EFcVM-1tP17u"))
("timestamp" . 1496071517968) ("recipient" ("id" . "474086316315717"))
("sender" ("id" . "1695095647186162"))))
("time" . 1496071518212) ("id" . "474086316315717")))
CL-USER> (length entries)
1
然後我定義了兩個函數工作與此:
(defun extract-entry (entry)
(let ((id (cdr (assoc "id" entry :test #'string=)))
(time (cdr (assoc "time" entry :test #'string=)))
(messaging (cdr (assoc "messaging" entry :test #'string=))))
messaging))
(defun extract-messaging (event)
(let ((message (cdr (assoc "message" event :test #'string=))))
message))
然後我操作:
CL-USER> (defparameter messaging (extract-entry (first entries)))
MESSAGING
CL-USER> messaging
((("message" ("text" . "hola") ("seq" . 3227)
("mid" . "mid.$cAAGvLYgmIaVihhT_EFcVM-1tP17u"))
("timestamp" . 1496071517968) ("recipient" ("id" . "474086316315717"))
("sender" ("id" . "1695095647186162"))))
CL-USER> (length messaging)
1
CL-USER> (defparameter message (extract-messaging (first messaging)))
MESSAGE
CL-USER> message
(("text" . "hola") ("seq" . 3227)
("mid" . "mid.$cAAGvLYgmIaVihhT_EFcVM-1tP17u"))
CL-USER> (length message)
3
而且它工作得很好,那麼我想申請generic-sequences此部分:
CL-USER> (gen-seq:seq->list (gen-seq:seq-map #'extract-messaging messaging))
((("text" . "hola") ("seq" . 3227)
("mid" . "mid.$cAAGvLYgmIaVihhT_EFcVM-1tP17u")))
CL-USER> (gen-seq:seq->list (gen-seq:seq-map #'extract-entry entries))
(((("message" ("text" . "hola") ("seq" . 3227)
("mid" . "mid.$cAAGvLYgmIaVihhT_EFcVM-1tP17u"))
("timestamp" . 1496071517968) ("recipient" ("id" . "474086316315717"))
("sender" ("id" . "1695095647186162")))))
和它的工作,但是當我串連的功能我得到這個問題:
CL-USER> (trace extract-entry extract-messaging)
(EXTRACT-ENTRY EXTRACT-MESSAGING)
CL-USER> (gen-seq:seq->list (gen-seq:seq-map #'extract-messaging (gen-seq:seq-map #'extract-entry entries)))
0: (EXTRACT-ENTRY
(("messaging"
(("message" ("text" . "hola") ("seq" . 3227)
("mid" . "mid.$cAAGvLYgmIaVihhT_EFcVM-1tP17u"))
("timestamp" . 1496071517968) ("recipient" ("id" . "474086316315717"))
("sender" ("id" . "1695095647186162"))))
("time" . 1496071518212) ("id" . "474086316315717")))
0: EXTRACT-ENTRY returned
((("message" ("text" . "hola") ("seq" . 3227)
("mid" . "mid.$cAAGvLYgmIaVihhT_EFcVM-1tP17u"))
("timestamp" . 1496071517968) ("recipient" ("id" . "474086316315717"))
("sender" ("id" . "1695095647186162"))))
0: (EXTRACT-MESSAGING
((("message" ("text" . "hola") ("seq" . 3227)
("mid" . "mid.$cAAGvLYgmIaVihhT_EFcVM-1tP17u"))
("timestamp" . 1496071517968) ("recipient" ("id" . "474086316315717"))
("sender" ("id" . "1695095647186162")))))
; Evaluation aborted on #<TYPE-ERROR expected-type:
"(OR (VECTOR CHARACTER) (VECTOR NIL) BASE-STRING SYMBOL CHARACTER)"
datum: ("message" ("text" . "hola") ("seq" . 3227) ..)>.
這個輸出調試器:
The value
("message" ("text" . "hola") ("seq" . 3227)
("mid" . "mid.$cAAGvLYgmIaVihhT_EFcVM-1tP17u"))
is not of type
(OR (VECTOR CHARACTER) (VECTOR NIL) BASE-STRING SYMBOL
CHARACTER)
when binding SB-IMPL::STRING2
[Condition of type TYPE-ERROR]
Restarts:
0: [*ABORT] Return to SLIME's top level.
1: [ABORT] abort thread (#<THREAD "repl-thread" RUNNING {1003180003}>)
Backtrace:
0: (STRING= "message" ("message" ("text" . "hola") ("seq" . 3227) ("mid" . "mid.$cAAGvLYgmIaVihhT_EFcVM-1tP17u"))) [more]
1: (SB-KERNEL:%ASSOC-TEST "message" #<unavailable argument> #<FUNCTION STRING=>)
2: (EXTRACT-MESSAGING ((("message" # # #) ("timestamp" . 1496071517968) ("recipient" #) ("sender" #))))
3: (SB-DEBUG::TRACE-CALL #<SB-DEBUG::TRACE-INFO EXTRACT-MESSAGING> #<FUNCTION EXTRACT-MESSAGING> ((("message" # # #) ("timestamp" . 1496071517968) ("recipient" #) ("sender" #))))
4: ((LABELS GENERIC-SEQ::TRAVERSE :IN GENERIC-SEQ::SEQ-MAP-1) (((# # # #)) . #<CLOSURE (LAMBDA NIL :IN GENERIC-SEQ::SEQ-MAP-1) {1004CF1F5B}>))
5: (GENERIC-SEQ:SEQ->LIST #S(GENERIC-SEQ::BASIC-SEQ :DELAYED-ENUM #<CLOSURE (LAMBDA NIL :IN GENERIC-SEQ::SEQ-MAP-1) {1004C9A46B}>))
6: (SB-INT:SIMPLE-EVAL-IN-LEXENV (GENERIC-SEQ:SEQ->LIST (GENERIC-SEQ:SEQ-MAP (FUNCTION EXTRACT-MESSAGING) (GENERIC-SEQ:SEQ-MAP # ENTRIES))) #<NULL-LEXENV>)
7: (EVAL (GENERIC-SEQ:SEQ->LIST (GENERIC-SEQ:SEQ-MAP (FUNCTION EXTRACT-MESSAGING) (GENERIC-SEQ:SEQ-MAP # ENTRIES))))
8: (SWANK::%EVAL-REGION "(gen-seq:seq->list (gen-seq:seq-map #'extract-messaging (gen-seq:seq-map #'extract-entry entries))) ..)
9: ((LAMBDA NIL :IN SWANK::%LISTENER-EVAL))
10: (SWANK-REPL::TRACK-PACKAGE #<CLOSURE (LAMBDA NIL :IN SWANK::%LISTENER-EVAL) {1004C9A1CB}>)
11: (SWANK::CALL-WITH-BUFFER-SYNTAX NIL #<CLOSURE (LAMBDA NIL :IN SWANK::%LISTENER-EVAL) {1004C9A1AB}>)
12: (SWANK::%LISTENER-EVAL "(gen-seq:seq->list (gen-seq:seq-map #'extract-messaging (gen-seq:seq-map #'extract-entry entries))) ..)
13: (SB-INT:SIMPLE-EVAL-IN-LEXENV (SWANK-REPL:LISTENER-EVAL "(gen-seq:seq->list (gen-seq:seq-map #'extract-messaging (gen-seq:seq-map #'extract-entry entries))) ..)
14: (EVAL (SWANK-REPL:LISTENER-EVAL "(gen-seq:seq->list (gen-seq:seq-map #'extract-messaging (gen-seq:seq-map #'extract-entry entries))) ..)
15: (SWANK:EVAL-FOR-EMACS (SWANK-REPL:LISTENER-EVAL "(gen-seq:seq->list (gen-seq:seq-map #'extract-messaging (gen-seq:seq-map #'extract-entry entries))) ..)
16: (SWANK::PROCESS-REQUESTS NIL)
17: ((LAMBDA NIL :IN SWANK::HANDLE-REQUESTS))
18: ((LAMBDA NIL :IN SWANK::HANDLE-REQUESTS))
19: (SWANK/SBCL::CALL-WITH-BREAK-HOOK #<FUNCTION SWANK:SWANK-DEBUGGER-HOOK> #<CLOSURE (LAMBDA NIL :IN SWANK::HANDLE-REQUESTS) {100317FFEB}>)
20: ((FLET SWANK/BACKEND:CALL-WITH-DEBUGGER-HOOK :IN "/Users/toni/.roswell/lisp/slime/2017.02.27/swank/sbcl.lisp") #<FUNCTION SWANK:SWANK-DEBUGGER-HOOK> #<CLOSURE (LAMBDA NIL :IN SWANK::HANDLE-REQUESTS) {..
21: (SWANK::CALL-WITH-BINDINGS ((*STANDARD-INPUT* . #1=#<SWANK/GRAY::SLIME-INPUT-STREAM {100309EAE3}>) (*STANDARD-OUTPUT* . #2=#<SWANK/GRAY::SLIME-OUTPUT-STREAM {1003167973}>) (*TRACE-OUTPUT* . #2#) (*ERR..
22: (SWANK::HANDLE-REQUESTS #<SWANK::MULTITHREADED-CONNECTION {10030004A3}> NIL)
23: ((FLET #:WITHOUT-INTERRUPTS-BODY-1159 :IN SB-THREAD::INITIAL-THREAD-FUNCTION-TRAMPOLINE))
24: ((FLET SB-THREAD::WITH-MUTEX-THUNK :IN SB-THREAD::INITIAL-THREAD-FUNCTION-TRAMPOLINE))
25: ((FLET #:WITHOUT-INTERRUPTS-BODY-358 :IN SB-THREAD::CALL-WITH-MUTEX))
26: (SB-THREAD::CALL-WITH-MUTEX #<CLOSURE (FLET SB-THREAD::WITH-MUTEX-THUNK :IN SB-THREAD::INITIAL-THREAD-FUNCTION-TRAMPOLINE) {8A4DCFB}> #<SB-THREAD:MUTEX "thread result lock" owner: #<SB-THREAD:THREAD "..
27: (SB-THREAD::INITIAL-THREAD-FUNCTION-TRAMPOLINE #<SB-THREAD:THREAD "repl-thread" RUNNING {1003180003}> NIL #<CLOSURE (LAMBDA NIL :IN SWANK-REPL::SPAWN-REPL-THREAD) {100317FF6B}> (#<SB-THREAD:THREAD "re..
28: ("foreign function: call_into_lisp")
29: ("foreign function: new_thread_trampoline")
30: ("foreign function: _pthread_body")
31: ("foreign function: _pthread_body")
32: ("foreign function: thread_start")
在這一點上問題是extract-entry返回一個列表,所以我應該像這樣工作:
CL-USER> (apply #'mapcar #'extract-messaging (mapcar #'extract-entry entries))
0: (EXTRACT-ENTRY
(("messaging"
(("message" ("text" . "hola") ("seq" . 3227)
("mid" . "mid.$cAAGvLYgmIaVihhT_EFcVM-1tP17u"))
("timestamp" . 1496071517968) ("recipient" ("id" . "474086316315717"))
("sender" ("id" . "1695095647186162"))))
("time" . 1496071518212) ("id" . "474086316315717")))
0: EXTRACT-ENTRY returned
((("message" ("text" . "hola") ("seq" . 3227)
("mid" . "mid.$cAAGvLYgmIaVihhT_EFcVM-1tP17u"))
("timestamp" . 1496071517968) ("recipient" ("id" . "474086316315717"))
("sender" ("id" . "1695095647186162"))))
0: (EXTRACT-MESSAGING
(("message" ("text" . "hola") ("seq" . 3227)
("mid" . "mid.$cAAGvLYgmIaVihhT_EFcVM-1tP17u"))
("timestamp" . 1496071517968) ("recipient" ("id" . "474086316315717"))
("sender" ("id" . "1695095647186162"))))
0: EXTRACT-MESSAGING returned
(("text" . "hola") ("seq" . 3227)
("mid" . "mid.$cAAGvLYgmIaVihhT_EFcVM-1tP17u"))
((("text" . "hola") ("seq" . 3227)
("mid" . "mid.$cAAGvLYgmIaVihhT_EFcVM-1tP17u")))
但隨後失敗,圖書館工作:
CL-USER> (apply #'gen-seq:seq-map #'extract-messaging (gen-seq:seq-map #'extract-entry entries))
attempt to use VALUES-LIST on a dotted list:
#S(GENERIC-SEQ::BASIC-SEQ
:DELAYED-ENUM #<CLOSURE (LAMBDA()
:IN
GENERIC-SEQ::SEQ-MAP-1) {100499978B}>)
[Condition of type SIMPLE-TYPE-ERROR]
Restarts:
0: [*ABORT] Return to SLIME's top level.
1: [ABORT] abort thread (#<THREAD "repl-thread" RUNNING {1003160003}>)
Backtrace:
0: (APPLY #<FUNCTION GENERIC-SEQ:SEQ-MAP> #<CLOSURE SB-IMPL::ENCAPSULATION {1002E5970B}> #S(GENERIC-SEQ::BASIC-SEQ :DELAYED-ENUM #<CLOSURE (LAMBDA NIL :IN GENERIC-SEQ::SEQ-MAP-1) {100499978B}>))
1: (SB-INT:SIMPLE-EVAL-IN-LEXENV (APPLY (FUNCTION GENERIC-SEQ:SEQ-MAP) (FUNCTION EXTRACT-MESSAGING) (GENERIC-SEQ:SEQ-MAP (FUNCTION EXTRACT-ENTRY) ENTRIES)) #<NULL-LEXENV>)
2: (EVAL (APPLY (FUNCTION GENERIC-SEQ:SEQ-MAP) (FUNCTION EXTRACT-MESSAGING) (GENERIC-SEQ:SEQ-MAP (FUNCTION EXTRACT-ENTRY) ENTRIES)))
3: (SWANK::%EVAL-REGION "(apply #'gen-seq:seq-map #'extract-messaging (gen-seq:seq-map #'extract-entry entries)) ..)
4: ((LAMBDA NIL :IN SWANK::%LISTENER-EVAL))
5: (SWANK-REPL::TRACK-PACKAGE #<CLOSURE (LAMBDA NIL :IN SWANK::%LISTENER-EVAL) {100499951B}>)
6: (SWANK::CALL-WITH-BUFFER-SYNTAX NIL #<CLOSURE (LAMBDA NIL :IN SWANK::%LISTENER-EVAL) {10049994FB}>)
7: (SWANK::%LISTENER-EVAL "(apply #'gen-seq:seq-map #'extract-messaging (gen-seq:seq-map #'extract-entry entries)) ..)
8: (SB-INT:SIMPLE-EVAL-IN-LEXENV (SWANK-REPL:LISTENER-EVAL "(apply #'gen-seq:seq-map #'extract-messaging (gen-seq:seq-map #'extract-entry entries)) ..)
9: (EVAL (SWANK-REPL:LISTENER-EVAL "(apply #'gen-seq:seq-map #'extract-messaging (gen-seq:seq-map #'extract-entry entries)) ..)
10: (SWANK:EVAL-FOR-EMACS (SWANK-REPL:LISTENER-EVAL "(apply #'gen-seq:seq-map #'extract-messaging (gen-seq:seq-map #'extract-entry entries)) ..)
11: (SWANK::PROCESS-REQUESTS NIL)
12: ((LAMBDA NIL :IN SWANK::HANDLE-REQUESTS))
13: ((LAMBDA NIL :IN SWANK::HANDLE-REQUESTS))
14: (SWANK/SBCL::CALL-WITH-BREAK-HOOK #<FUNCTION SWANK:SWANK-DEBUGGER-HOOK> #<CLOSURE (LAMBDA NIL :IN SWANK::HANDLE-REQUESTS) {100315FFEB}>)
15: ((FLET SWANK/BACKEND:CALL-WITH-DEBUGGER-HOOK :IN "/Users/toni/.roswell/lisp/slime/2017.02.27/swank/sbcl.lisp") #<FUNCTION SWANK:SWANK-DEBUGGER-HOOK> #<CLOSURE (LAMBDA NIL :IN SWANK::HANDLE-REQUESTS) {..
16: (SWANK::CALL-WITH-BINDINGS ((*STANDARD-INPUT* . #1=#<SWANK/GRAY::SLIME-INPUT-STREAM {100307F5A3}>) (*STANDARD-OUTPUT* . #2=#<SWANK/GRAY::SLIME-OUTPUT-STREAM {1003147DD3}>) (*TRACE-OUTPUT* . #2#) (*ERR..
17: (SWANK::HANDLE-REQUESTS #<SWANK::MULTITHREADED-CONNECTION {10030004A3}> NIL)
18: ((FLET #:WITHOUT-INTERRUPTS-BODY-1159 :IN SB-THREAD::INITIAL-THREAD-FUNCTION-TRAMPOLINE))
19: ((FLET SB-THREAD::WITH-MUTEX-THUNK :IN SB-THREAD::INITIAL-THREAD-FUNCTION-TRAMPOLINE))
20: ((FLET #:WITHOUT-INTERRUPTS-BODY-358 :IN SB-THREAD::CALL-WITH-MUTEX))
21: (SB-THREAD::CALL-WITH-MUTEX #<CLOSURE (FLET SB-THREAD::WITH-MUTEX-THUNK :IN SB-THREAD::INITIAL-THREAD-FUNCTION-TRAMPOLINE) {8A57CFB}> #<SB-THREAD:MUTEX "thread result lock" owner: #<SB-THREAD:THREAD "..
22: (SB-THREAD::INITIAL-THREAD-FUNCTION-TRAMPOLINE #<SB-THREAD:THREAD "repl-thread" RUNNING {1003160003}> NIL #<CLOSURE (LAMBDA NIL :IN SWANK-REPL::SPAWN-REPL-THREAD) {100315FF6B}> (#<SB-THREAD:THREAD "re..
23: ("foreign function: call_into_lisp")
24: ("foreign function: new_thread_trampoline")
25: ("foreign function: _pthread_body")
26: ("foreign function: _pthread_body")
27: ("foreign function: thread_start")
的問題是相同的,但後來我可以解決這個問題:
CL-USER> (gen-seq:seq->list (apply #'gen-seq:seq-map #'extract-messaging (gen-seq:seq->list (gen-seq:seq-map #'extract-entry entries))))
0: (EXTRACT-ENTRY
(("messaging"
(("message" ("text" . "hola") ("seq" . 3227)
("mid" . "mid.$cAAGvLYgmIaVihhT_EFcVM-1tP17u"))
("timestamp" . 1496071517968) ("recipient" ("id" . "474086316315717"))
("sender" ("id" . "1695095647186162"))))
("time" . 1496071518212) ("id" . "474086316315717")))
0: EXTRACT-ENTRY returned
((("message" ("text" . "hola") ("seq" . 3227)
("mid" . "mid.$cAAGvLYgmIaVihhT_EFcVM-1tP17u"))
("timestamp" . 1496071517968) ("recipient" ("id" . "474086316315717"))
("sender" ("id" . "1695095647186162"))))
0: (EXTRACT-MESSAGING
(("message" ("text" . "hola") ("seq" . 3227)
("mid" . "mid.$cAAGvLYgmIaVihhT_EFcVM-1tP17u"))
("timestamp" . 1496071517968) ("recipient" ("id" . "474086316315717"))
("sender" ("id" . "1695095647186162"))))
0: EXTRACT-MESSAGING returned
(("text" . "hola") ("seq" . 3227)
("mid" . "mid.$cAAGvLYgmIaVihhT_EFcVM-1tP17u"))
((("text" . "hola") ("seq" . 3227)
("mid" . "mid.$cAAGvLYgmIaVihhT_EFcVM-1tP17u")))
但是,當我這樣做,我失去了懶評估術語如此,我怎樣才能在不失去通用序列中的懶惰評估的情況下實現它。
看起來有太多的列表級別。 ASSOC沒有得到關聯列表。它得到一個關聯列表的列表。 EXTRACT -MESSAGING相同... –
如果一個函數需要一個關聯列表作爲參數,我會向該函數的主體添加一個ASSERT語句,該語句檢查它實際上是否是一個正確的關聯列表。 –