我正在使用messenger api from facebook使用ningle。在我的计划中有一个时刻,我需要使用来自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")))
但是当我这样做时,我失去了对该术语的懒惰评价,那么如何在不失去通用序列中的惰性评估的情况下实现它。
答案 0 :(得分:4)
如果您的函数处理关联列表,您可能会检查它们是否实际上获得了具有如下函数的有效关联列表:
CL-USER 106 > (get-age '((name . ute) (age . 34)))
34
CL-USER 107 > (get-age '(((name . ute) (age . 34))))
Error: Not a valid assoc list: (((NAME . UTE) (AGE . 34)))
1 (continue) Retry assertion with new value for ALIST.
2 (abort) Return to level 0.
3 Return to top loop level 0.
示例:
dos2unix optionsList.txt
dos2unix optionsList.txt optionsList.txt
这可能会降低性能,一旦您的代码正常运行,您可能会将其删除。