2014-11-10 3 views
3

목록을 취소하려고합니다.haskell에서 목록 반전

reverseList :: [Int] -> [Int] 
reverseList [] = [] 
reverseList (x:xs) = x:reverseList xs 

무슨 일이 끝나는 것은 내가 다시 같은 순서로 목록을 그만 둘 수 있습니다 : 다음

내 코드입니다. 나는 목록을 역전시키는 방법에 대한 해답을 가지고있다. 그러나 내가 여기서 잘못한 것을 이해하려고 노력하고있다. 나는 haskell에 매우 익숙하다. 그래서 나는 더 많은 문제를 더 쉽게 해결할 수있는 이해에 집중해야한다고 생각한다. 나는이 문제에 대해 많은 해결책을 알고 있지만이 코드에서 내가 잘못한 것을 이해하는데 도움이 더 필요하다.

답변

2

목록을 머리와 꼬리로 분리하지만 같은 순서로 목록을 다시 조립하십시오. 예를 들어 목록 [1, 2, 3]을 가지고 :

을 첫 번째 통화에서 x1 될 것이며, xs[2, 3] 될 것입니다. 그런 다음 x (앞에 1)으로 구성된 새 목록을 작성한 다음 reverseList [2, 3을 입력하십시오.

+0

죄송합니다. 수정 됨. –

+0

나는 똑같은 일을하지 않는다. 왜냐하면 머리를 꺼낼 때 x와 같은 머리를 먼저 삽입하기 때문이다 : reverseList xs – user1010101

25

하스켈에서이 문제를 해결할 수있는 몇 가지 방법이 있습니다. 하스켈 목록은 정말 단독으로 목록을 연결되어 있기 때문에 당신이를 통과 할 수있는 요소를 추가하기 위해, 그래서, 그러나

reverseList [] = [] 
reverseList (x:xs) = reverseList xs ++ [x] 

, 이것은 큰 목록에 대한 정말 느려집니다 : 순진 방법은 CONCATENATE 기능 ++를 사용하는 것 전체 목록. 그래서,

reverseList = foldl (\acc x -> x : acc) [] 

그러나 \acc x -> x : acc 그냥 flip (:)입니다 :

reverseList = go [] 
    where 
     go acc [] = acc 
     go acc (x:xs) = go (x:acc) xs 

그러나, 이것은 단지 fold 패턴이 정말 : 대안은 당신이 도우미 함수에 구축하고있는 목록을 유지하는 것 이것은 그러나

reverseList = foldl (flip (:)) [] 

과 같이 쓸 수있다, 가장 쉬운 방법은 아마 그냥 reverse를 functi를 사용하는 것 Prelude에서.

reverseList :: [Int] -> [Int]의 유형이 :: [a] -> [a]으로 일반화 될 수 있다는 점을 지적하고 싶습니다. 목록의 요소와 관련하여 특별한 것은하지 않고 단지 새로운 목록을 작성하는 것입니다.

+1

완전성을 위해, 게으른 양식'foldl '은 훨씬 좋다. –

+0

@PierreR 엄격한 형식을 의미하지 않습니까? 그리고 나는 그것을 알고 있습니다, 나는 방금 여분의 수입과 두 가지 사이의 차이점을 언급하는 것을 피하고있었습니다. 그것은 SO에서 너무 많이 설명했습니다.) – bheklilr

+0

예 ... 물론 엄격합니다. 나는 당신이 그것에 대해 알았던 것은 의심 할 여지가 없다. 당신의 대답은 그토록 귀중한 도움이됩니다. 시간을내어 주셔서 감사합니다. –