난 당신이 "다음"에 op-result
를 사용하려면 같은데요 하지만 많은 프리디 케이트 함수 tions는 그들의 논쟁이 아닌 true
을 반환합니다. 그래서 당신은 단순히이 쓸 수 없습니다 :
(and (pred x) x)
당신은
(if-let [op-result (and (pred (op)) (op))]
op-result
false)
쓸 수 그러나 (op)
비싼 경우,이 낫다 :
이
(if-let [op-result (pred (op))]
op-result ;maybe `true`, but you want `(op)`
false)
당신이 원하는 핵심 표현은 다음과 같습니다
(if-let [op-result (let [x (op)] (and (pred x) x))]
op-result
false)
물론 약간 지루한데, 그렇게 많이 필요하다면 매크로를 작성하는 것이 좋습니다.
나는 또 다른 접근 방식은 술어가 "truthy"하는 것입니다 가정 :
(defn truthy
"Given a predicate function, return a new function.
When the original predicate function returns true for some value,
the new function returns the value (instead of true). Else returns
false."
[pred]
(fn [v]
(and (pred v) v)))
((truthy even?) 2) ; 2
((truthy even?) 3) ; false
(if-let [op-result ((truthy pred) (op))]
op-result ;use op-result
false)
다시, 매크로 편리 할 수 있습니다.
일부 Lisps에서 나는 (이맥스 리스프에서 라켓에 match
, pcase
) 패턴 매칭을 사용하십시오. 이들은 cond
과 같은 형태입니다. 종종 원래 값을 바인딩하는 동안 테스트에 대한 조건부를 적용 할 수있게합니다. core.match
이이 작업을 수행 할 수 있는지 또는이 작업을 단독으로 수행하려는 경우 확실하지 않습니다.
마지막으로, 나는 완전히 다른 사람이 같은 이미 나도 몰라 Clojure에서의 한 - 라이너로 존재 함을 지적 할 전망이다. :) 그러나 나는 아무도 가지고 있지 않았기 때문에 나는 대답을 시도 할 것이라고 생각했다.
"my-var"에 "op-result"를 생략 할 수 있기 때문에 간단한 '(if (pred op-result) then else)'만 쓸 수 있습니다. 아니면 당신의 본보기가 더 복잡한가? – ClojureMostly