2013-11-04 2 views
4

내가 가장 짧은, 우아하고 관용적 인 방법이 무엇인지 기능의 목록, 어떤 종류의 형태 a -> a 각각있는 경우 그들을 결합하기 위하여; 바람직하게 여분의 의존성을 추가하지 않고?대부분의 관용적 구현`[A -> A] -> (A -> A)`

일부 변종은

foo (x:xs) = x . (foo xs) 
foo [] = id 

foo = foldr (.) id 

foo = appEndo . mconcat . map Endo 

을 포함하지만 어떤 이유로 나는 더 좋은 뭔가를 찾을 것으로 기대하고있다.

+8

'foldr id' 없음? – jozefg

+0

물론입니다. –

+2

'foldr' 버전과는 무엇이 다릅니 까? 정확히 12 자이므로 명확하지 않으며 종속성이없고 재귀의 모든 세부 사항을 추상화합니다. – jozefg

답변

19

난 당신이

comp = foldr (.) id 

이유를 이길 않을거야라고 말하고 싶지만? 우리는 일의 목록을 가지고 있으며, 우리는 그것을 올바른 연관성있는 방식으로 줄이려고 노력하고 있습니다. 당신이 and, sum, maximum 및 유사의 구현을 보면

,이 그들이 표준 라이브러리에서 구현하는 방법입니다 것을 볼 수 있습니다, 난 당신보다 더 관용적 얻을 생각하지 않는다 :

Tangent : maximum 분명히 있어야하는 부분과 달리 예상치 못한 부분적인 행동으로 코멘트에 언급 된 foldr1 변형을 추가하는 것을 주저합니다.

+0

'및','sum','maximum' 등의 구현을 보면'foldr (.) id'의 이름이 왜 없습니까? –

+0

@JoachimBreitner 그건 나쁜 질문이 아닙니다.) 불행히도 나는 "아마 무작위 적 기회"이외의 대답이 없다. – jozefg

6

하지 않을 수 있습니다 또 하나,보다 짧은 foldr (.) id하지만 난 생각이 귀엽다 : (.) ​​

foo = flip (foldr id) 
+3

처음에는 (나 같은)이 혼란스럽고,'a -> b -> b '유형의 함수로'id'를 사용하여'a' 'b -> b'형식을 사용합니다. 그래서 foldr id (foldr의 타입은 (a -> b -> b) -> b -> [a -> b')이고, 타입은'b -> [b -> b] -> b'이므로 'flip (foldr id)'는'[c -> c] -> (c -> c)'와 같은 [c -> c] -> c -> c 유형을 가지고 있습니다. – Squidly

+4

더 명확히하기 위해, 'id '의 사용은 종종'($)'로 알려져 있습니다. '($)'는 더 특정한 형 ('a -> a' 대신에'(a -> b) -> a -> b)을 가진'id'입니다. 나는 그가 더 짧기 때문에 그가 여기에서'id '를 사용했다고 믿습니다. 이 솔루션을 쓸 때'foo l x = foldr ($) x l'로 쓸 수 있습니다. 이것은'foo lx = l1 $ l2 $ l3 $ l4 $ .. ln $ x'과 같은 일을 볼 수있게합니다. 이것은 물론'(l1. l3. l4. .. ln) x'는 jozefg의 해답입니다. – newacct