2014-09-29 6 views
3

우리는 reduce/foldl1을 함수 by which we can define other higher order functions such as map, filter and reverse으로 사용할 수 있음을 알 수 있습니다.폴드 및 축소가 근본적인 이유 인 이유는 무엇입니까? 물론 모든 것이 단점과 자동차 측면에서 정의되어 있습니까?

(defn mapl [f coll] 
    (reduce (fn [r x] (conj r (f x))) 
      [] coll)) 

(defn filterl [pred coll] 
    (reduce (fn [r x] (if (pred x) (conj r x) r)) 
      [] coll)) 

(defn mapcatl [f coll] 
    (reduce (fn [r x] (reduce conj r (f x))) 
      [] coll)) 

우리는 또한 foldr의 관점에서이를 수행 할 수있는 것으로 보입니다. 여기에 mapfilter은 012:의 17:25로 표시됩니다. fold와 왜

(defn foldr [f z xs] 
    (if (null? xs) 
     z 
     (f (first xs) (foldr f z (rest xs))))) 

(defn foldl [f z xs] 
    (if (null? xs) 
     z 
     (foldl f (f z (first xs)) (rest xs)))) 

(defn map [f lst] 
    (if (null? lst) 
     '() 
     (cons (f (first lst)) (map f (rest lst))))) 

내 질문이 입니다 :

(defn mapr [f coll] 
    (foldr (fn [x r] (cons (f x) r)) 
     () coll)) 

(defn filterr [pred coll] 
    (foldr (fn [x r] (if (pred x) (cons x r) r)) 
     () coll)) 

이제 우리는 first, restcons (car, cdrcons)의 측면에서 map, foldl (reduce)와 foldr 정의 할 수 있습니다 reduce은 기본으로 간주됩니다. 확실히 모든 것이 cons, cdrcar? 잘못된 레벨의 것들이 보이지 않습니까?

+2

([바나나, 렌즈, 봉투 및 철조망과 기능 프로그래밍] http://wwwhome.ewi.utwente.nl/~fokkinga/mmf91m.pdf :

당신은이 논문에서 자세한 내용을보실 수 있습니다) 관련성이 있습니다. Clojure의 구현 방식이 있습니다. 그렇지만, 물건을 기술하는 수학적 방법도 있습니다. –

+0

정말 그 주석에 감사드립니다. Matt - 우리가 분류 할 수있는 몇 개의 '빌딩 블록 시작 장소'가 있는지 궁금합니다. 어떤 사람들은 Lisp가 Maxwell의 방정식 인 http://www.michaelnielsen.org/ddi/lisp-as-the-maxwells-equations-of-software/라고 말하지만,이 Q & A의 주제는 '목록'을 만들고, 때때로 여러분은'fold'를 사용하여 비 목록 구조를 변형하려고합니다. – hawkeye

+0

'cons','car','cdr'는 객관적인 의미에서 원시적이 아니기 때문에 모든 것을'λ '만으로 정의 할 수 있습니다. 그렇다면 왜 다른 것들 대신에이 세 가지의 특정 원시 연산으로 모든 것을 줄여 줄 것을 부탁드립니다. 그것은 모두 친척입니다. – amalloy

답변

6

Rich Hickey가 정확하게 그의 것이라고 말한 것으로 생각했습니다 talk about transducers.

그는 변형의 기본 개념으로 folds을 봅니다. 그것은 그것이 작동하고있는 구조와 그 구조에서 작동하는 방법을 알 필요가 없습니다.

방금 ​​foldcdr, carrest으로 정의했습니다. 리치가 주장하는 것은 fold 그 자체가 그것이 작동하는 데이터 구조와는 별도의 추상 개념이며, 실제로 데이터 구조에서 작동하는 특정 기능을 제공하는 한 예상대로 작동한다는 것입니다.

그래서 궁극적으로는 관심사와 재사용 가능성을 분리하는 것입니다.

0

폴드는 귀납적 인 데이터 정의에 해당하기 때문에 원칙적으로 데이터 처리를위한 통일 ​​된 프레임 워크입니다. 그들은 특별하지 않습니다. cons/car/cdr은 데이터 (및 코드)를 작성하기위한 빌딩 블록이지만 비처방 방법은 아닙니다 (우리는 무엇이든 할 수 있고 그것을 임시로 처리 할 수 ​​있습니다). 겹은 더 높은 수준, 더 규율되고 예측 가능하며 추론하기 쉽습니다.

목록에 map, filter, mapcat에 대한 임시 구현이 주어지면 비슷한 구조가 있음을 알 수 있습니다. 데이터 구조를 따르는 코드 구조 (목록, 죄수 노드를 기반으로합니다. 결합 함수의 두 인수). 그리고 그것은 배입니다.

그 이야기에서 Rich Hickey는 단계 기능을 추상화합니다. 그러나 그는 데이터를 추상화하지 않습니다. 레이블이있는 나무를 접는 데 사용되는 결합 함수는 두 개가 아니라 세 개의 매개 변수를 사용해야합니다. 따라서 그의 -ing 함수가하는 일은 개념적으로 목록에서 접는 것입니다. 그것은 단지리스트의 구체적인 구현을 추상화하는 것입니다 - 단점 셀, 해시 된 배열 트리, 무엇이든간에.

+0

예 - '모든 것이 목록이 아닐 때'와 같은 Lispers에게는 상당히 충격적입니다. 그리고 비 목록 데이터 구조를 변형 할 수있는 HOF가 필요합니다. 정말이 대답을 주셔서 감사합니다. – hawkeye

+0

목록 데이터도 변환하려면 HOF가 필요합니다. (나는 마음의 상태에서 "상위 레벨"을 의미했다.) 폴드는 개념적으로 데이터 유형과 직접적인 관련이있다. [교회 인코딩] (https://en.wikipedia.org/wiki/Church_encoding#Represent_the_list_using_right_fold)은 한 배입니다. BTW는 매우 흥미로운 업적이며,이 분리이며, * 추상화와 같은 단순하고 기본적인 도구를 사용합니다. Abelson과 Sussman은 자랑스러워 할 수 있습니다. :) 그것은 잘 알려진 문제이며 Haskell에서 예를 들어. 모든 데이터 유형은 구체적입니다. –

0

불규칙한 언어로 된 대부분의 연산자에는 정의 할 수있는 파트너가 있으며, 그 반대의 경우도 마찬가지입니다. 이 속성을 "metacircularity"라고합니다. 언어가 제공하는 프로그래밍 기능의 전체 집합을 허용하는 기본적인 기본 연산자는 없습니다. http://home.pipeline.com/~hbaker1/MetaCircular.html

+0

매력적인 주장. 이 질문은 그 가정에 동의하지 않습니다. http://stackoverflow.com/questions/3482389/how-many-primitives-does-it-take-to-build-a-lisp-machine-ten-seven-or-five 당신이 말한 종이는 잡아 당기고 레이블을 붙였습니다. 어쨌든 사람들이 근본적이라고 생각한 사람은 없다고 생각합니다. 아마도 귀하는 귀하의 청구에 대한 추가 참조를 제공 할 수 있습니까? – hawkeye

+0

글쎄요, comp.lang.lisp에는 ANSI 표준의 편집자가 어떤 연산자 집합을 기본 연산자로 정의해야하는지에 대한 논의가 논의되고 있습니다 (매크로 확장 및 코드 워커의 목적을 위해.) 이 시점에서 어떻게 찾을지를 결정할 수 있지만 결정이 내려 졌다는 증거를 원한다면 ANSI Common Lisp 표준의 "특수 연산자"목록을 볼 수 있습니다. 당신이 말하는 질문은 무엇이 근본적인 것인지에 대해서는 설명하지 않지만, 오히려 최초의 Lisp에 포함 된 것은 무엇인가. –