2013-07-03 2 views
1

사용하고있는 언어는 하스켈의 내장 함수를 사용할 수없는 코어 하스켈이라는 하스켈의 하위 집합입니다. 내가 항목 x는 목록 XS에 나타나는 횟수를 세는 함수를 작성한다면 예를 들어, 내가 작성합니다하위 집합 언어를 사용하여 함수 만들기 목록의 중복 항목을 제거하는 코어 하스켈

count = \x -> 
      \xs -> if null xs 
        then 0 
        else if x == head xs 
          then 1 + count x(tail xs) 
          else count x(tail xs) 

을 나는 목록을 출력하는 기능을 만들려고 해요 중복 값이 ​​제거 된 xs. 예 : remdups (7 : 7 : 7 : 4 : 5 : 7 : 4 : 4 : []) => (7 : 4 : 5 : [])

누구든지 어떤 조언을 해주실 수 있습니까?

감사합니다.

+1

꼬리가 Core Haskell에 있습니까? – DiegoNolan

+0

하스켈에서 작성하고 GHC에서 핵심 코드를 인쇄 할 수 없습니까? 이렇게하면 GHC 매뉴얼 만 공부하면됩니다. – Ingo

답변

2

나는 학생이 학생이라고 추측하고 있는데, 이는 숙제 문제이기 때문에 답변의 일부를 제공하고 끝내도록하겠습니다. remdups을 쓰려면 목록에 요소가 있는지 알려주는 함수가 유용 할 것입니다. 우리는 재귀를 사용하여 그렇게 할 수 있습니다. 재귀를 사용할 때 "기본 사례"또는 가장 간단한 가능한 사례가 무엇인지 직접 물어보십시오. 글쎄, 목록이 비어 있으면 분명히 대답은 False (문자가 무엇이든간에)입니다. 목록이 비어 있지 않으면 어떻게 될까요? 목록의 첫 번째 문자가 일치하는지 확인할 수 있습니다. 그렇다면 대답은 True입니다. 그렇지 않으면 함수 목록을 다시 호출하여 목록의 나머지 부분을 검사해야합니다.

밑줄 ( _)은 단순히 "이 변수를 사용하지 않을거야, 그래서 심지어 이름을 지정 귀찮게하지 않습니다."를 의미
elem _ []  = False 
elem x (y:ys) = if x==y 
        then True 
        else elem x ys 

즉, 같은 더 간결하게 작성할 수 있습니다

remdups 작성
elem _ []  = False 
elem x (y:ys) = x==y || elem x ys 

조금 까다 롭습니다,하지만 난 선생님이 당신에게 몇 가지 힌트를 준 생각한다. 그것에 접근하는 한 가지 방법은 우리가 목록을 처리하는 중간 단계라고 상상해 보는 것입니다. 우리는 아직 처리되지 않은 목록의 일부와 처리 된 목록의 일부 (중복을 포함하지 않음)를 가지고 있습니다. 우리가 이라는 함수를 가지고 있다고 가정하면,이 두 인자는 remainingfinished입니다. remaining의 첫 번째 문자를보고 해당 문자가 finished에 있는지 여부에 따라 다른 결과를 반환합니다. (그 결과는 remdupHelper을 재귀 적으로 호출 할 수 있습니다). remdupHelper을 쓸 수 있습니까? 당신이 remdupHelper가 있으면

remdupHelper = ??? 

, 당신은 remdups을 쓸 준비가 된 것입니다.

remdups l = remdupHelper l []    -- ' 
1

이 INTS와 함께 작동 : 그것은 단지 목록 중 어느 것도 아직 처리되지 않은 초기 상태에 remdupHelper를 호출

removeDuplicates :: [Int] -> [Int] 
removeDuplicates = foldr insertIfNotMember [] 
      where 
      insertIfNotMember item list = if (notMember item list) 
          then item : list 
          else list 

notMember :: Int -> [Int] -> Bool 
notMember item [] = True 
notMember item (x:xs) 
      | item == x = False 
      | otherwise = notMember item xs 

이 분명해야 작동 방법.유일한 "까다로운"부분 foldr의 종류가 있다는 것이다 :

(a -> b -> b) -> b -> [a] -> b 

그러나,이 경우, B는 [A]와 통합, 그래서된다 :

(a -> [a] -> [a]) -> [a] -> [a] -> [a] 

을 따라서는 통과 할 function insertIfNotMember :

Int -> [Int] -> [Int] -- a unifies with Int