2011-03-25 1 views
5

주어진 속성을 만족하는 항목에 따라 목록을 하위 목록으로 분할하는 함수를 작성하고 싶습니다. p. 내 질문은 함수를 호출하는 것입니다. 하스켈에서 예제를 드리 겠지만 F #이나 ML에서도 같은 문제가 발생할 것입니다.리스트를 분리하는 함수를 무엇이라고 부를까요?

split :: (a -> Bool) -> [a] -> [[a]] --- split lists into list of sublists 

하위 목록은 원래리스트 연결된 있습니다

concat (split p xss) == xs 

모든 하위 목록 말하고있는 initial_p_only p 특성을 만족하는 (A)가 하위 목록은 소자 p — 만족 시작하고 그러므로 비어 있지 및 (B) 다른 요소가 충족되지 p :

initial_p_only :: (a -> Bool) -> [a] -> Bool 
initial_p_only p [] = False 
initial_p_only p (x:xs) = p x && all (not . p) xs 

것은 그래서 될 원래 목록의 첫 번째 요소는 p을 만족하지 않는 경우

all (initial_p_only p) (split p xss) 

, 그것에 대해 정확한 분할에 실패합니다.

이 함수는 split 이외의 다른 함수로 호출해야합니다. 내가 뭐라고 부를까요 ??

+0

groupBy가 올바르게 보이지 않습니다. groupAt가 작동 할 수도 있습니다. –

+0

splitBy? splitBefore/After? – Daniel

+4

구현하지 않고 공식 사양을 작성하는 방법을 좋아합니다. – luqui

답변

12

나는 설명하는 기능이 이며, 패키지는 list-grouping입니다.

Data.List.Grouping

: http://hackage.haskell.org/packages/archive/list-grouping/0.1.1/doc/html/Data-List-Grouping.html

ghci> breakBefore even [3,1,4,1,5,9,2,6,5,3,5,8,9,7,9,3,2,3,8,4,6,2,6] 
[[3,1],[4,1,5,9],[2],[6,5,3,5],[8,9,7,9,3],[2,3],[8],[4],[6],[2],[6]] 
+0

+1은 이름을 제공 할뿐만 아니라 이미 구현 된 기능을 구현합니다. –

+1

겁나는. 내 코드는 이미 작성되었습니다. 친절하게 감사드립니다. –

+0

'break'자체가 튜플이 아닌리스트를 생성하기 때문에 나는 'break'의 평범한 변형을 좋아하지 않습니다. 어쩌면 복수는 너무 미묘한 것 말고는 '나누기'이전 일 수도 있습니다. 'unfoldBreaks'는 꽤 문자적인 이름입니다. – sclv

2

나는 아주 adamse에서 알 수 있듯이 용어는 "휴식"을 기반으로 몇 가지 이름이있다. 함수에는 몇 가지 가능한 변형이 있습니다. 여기에 내가 기대할 것입니다 (F # 라이브러리에서 사용 된 명명법을 기반으로 함).

단지 breakBefore는 중단해야하는 전에 요소를 걸릴 것이다라는 기능 :

breakBefore :: Eq a => a -> [a] -> [[a]] 

With 접미사 함수가 깰 때 직접 지정 기능의 어떤 종류를 취할 것입니다. 이 brekaing의 경우에는 당신이 원하는 기능 a -> Bool입니다 :

breakBeforeWith :: (a -> Bool) -> [a] -> [[a]] 
또한 By 접미사 기능이 키 선택기을하고 휴식 것이 상상할 수

때 조금 group by처럼 주요 변경 사항 (, 하지만 당신은 동일한 키를 가진 여러 그룹)을 가질 수 있습니다

breakBeforeBy :: Eq k => (a -> k) -> [a] -> [[a]] 

나는 이름이 조금 긴 받고 인정 - 어쩌면 정말 유용 유일한 기능은 당신이 원하는 사람입니다. 그러나 F # 라이브러리는이 패턴을 매우 일관되게 사용하고있는 것으로 보입니다 (예 : sort, sortBy 키 선택기 및 sortWith 비교기 기능 사용).

아마도이 세 가지 변형을 더 많은 목록 처리 함수에 사용할 수 있습니다 (그리고이 세 가지 유형에 대해 일관된 명명 패턴을 갖는 것이 좋습니다).

+0

나는 간단하게 mine'break : ('a -> bool) ->'a list -> 'list *'a list ' –