2011-02-06 7 views
3

저는 최근에이 문제를 어떤 형태로든 많이 보아 왔습니다. x를 취하여 y를 생성하는 x에 고차 함수를 적용하려고합니다. 그런 다음 y가 특정 속성을 만족하는지 확인합니다. 그렇다면 x를 반환하고 싶습니다.고차 함수를 통한 데이터 전달

이 문제는 숫자 목록 [x1, x2..xn]과 내가 적용하는 함수가 목록을 압축 할 때 매우 까다로운 것으로 보입니다. 예를 들어, 목록의 각 요소 ([y1, y2 ..] 생성), 정렬, 그룹에 함수를 적용한 다음 가장 큰 그룹에 대해 x 값을 반환하고자합니다. 예를 들면 :

head . reverse . sort . map (length) . group . sort . map (mod 4) $ [1..10] 

대답은 6이지만, 어떻게 이런 기능은 1 번부터 10 번까지 그 6에 속하는 요소 번호를 말해 다시 것인가?

나는 snd가 필요할 때까지 튜플을 전달하고 fst를 사용하는 생각을 가지고 놀았으며, 정렬과 같은 것으로 새로운 클래스를 작성하여 클래스의 한 요소에서만 작동하지만 나는 할 수 없다. 깨끗한 접근 방식을 생각해 낸 것 같습니다.

감사합니다.

답변

5

다음은 길이가 아닌 값을 반환하는 코드의 작은 변경 사항입니다. * 표시 By 기능의 사용은 튜플을 사용할 필요가 피할 수 :

maximumBy (compare `on` length) . groupBy ((==) `on` mod 4) . sortBy (compare `on` mod 4) $ [1..10] 

이 코드는 Data.List와 Data.Function이 필요합니다. Data.Function에는 on이 포함되어있어 입력의 일부 기능에 비교 (정렬 또는 그룹화)를 적용 할 수 있습니다.

+0

감사합니다. 이것은 내가 생각해 보았을 것보다 훨씬 깨끗합니다. 나는 이런 문제에 대한 일반적인 접근법이 없다는 것을 이해하기 시작했다. –

1

GHC의 TransformListComp extension을 사용하면 검색어를 직접 표현할 수 있습니다.

{-# LANGUAGE TransformListComp #-} 
import GHC.Exts 

input = [1..10] 
output = [ x 
     | x <- input 
     , let y = 4 `mod` x 
     , then group by y 
     , then sortWith by (-length x, the y) 
     ] 
-- output = [[5,6,7,8,9,10],[1,2,4],[3]] 
+0

확장 기능이 있다는 것을 몰랐고, 재미있어 보였습니다. –