Haskell #4 (An intro to lists)

--

이번 장에서는 하스켈의 리스트에 대해서 알아봅니다. 하스켈에서 리스트는 매우 유용하다고 합니다. 어떤 언어나 마찬가지이긴 하지만 엄청 자주 쓰는 자료구조입니다. 그만큼 중요하고 깊이 이해해야할 필요가 있다고 생각됩니다.

Ref: #4. Starting Out-”An intro to lists”

리스트는 같은 타입의 구성 요소를 여러개 넣을 수 있는 자료구조 입니다.

아래 예제에서 let은 GHCI에서 이름을 정의하기 위해서 사용되는 것으로 스크립트에서는 사용되지 않는 키워드입니다.

하스켈에서 리스트는 중괄호([])로 표시하고, 값들을 콤마(,)로 구분합니다. 만약 [1,2,’a’,3,’b’,’c’,4]와 같은 리스트를 만들기 위해서 시도하면 하스켈에서는 char는 숫자가 아니라는 에러를 발생 시킬 것입니다. 하스켈에서 “hello”라는 문자열은 [‘h’,’e’,’l’,’l’,’o’]라는 char의 리스트입니다.

하스켈에서는 두 리스트를 합칠 때, ++ 연산자를 사용합니다. 하스켈 내부적으로는 ++ 연산을 사용하면 ++ 왼쪽의 리스트 전체를 방문하는데, 거대한 리스트를 다루는게 아니라면 문제가 없습니다. 하지만 5000만개의 데이터를 가진 리스트의 끝에 추가하려면 시간이 필요할 것 입니다.

리스트의 앞에 넣을때는 : 연산자를 사용합니다. 이 연산자는 숫자나 숫자/문자의 리스트 또는 문자들의 리스트도 인자로 사용될 수 있습니다. 반면에 ++ 연산자는 두개의 리스트만 인자로 사용됩니다.

[1,2,3]이라는 리스트는 사실은 1:2:3:[]와 같습니다. 여기서 []은 비어있는 리스트입니다. 아래와 같은 표기는 모두 다른 리스트를 의미합니다.

  • [] : 빈 리스트
  • [[]] : 빈 리스트 한개를 포함하는 리스트
  • [[],[],[]] : 3개의 빈 리스트를 포함하는 리스트

리스트에서 특정 인덱스의 값을 얻어올때는 !! 연산자를 사용합니다.

리스트는 리스트를 포함할 수 있습니다. 리스트안의 리스트는 다른 길이를 가질 수 있지만 다른 타입의 값을 가지고 있는 리스트들이 공존할 수는 없습니다.

리스트는 리스트에 포함된 값으로 비교가 가능합니다. <, <=, >, >= 비교 연산자를 사용해서 두 리스트의 크기를 비교할 수 있습니다. 비교할때는 사전적인 순서로 비교가되고, 앞에서부터 비교가 됩니다.

하스켈에서는 리스트를 가지고 놀 수 있는 아래와 같은 기본 함수들을 제공합니다.

  • head : 리스트의 첫번째 값을 가져옵니다.
  • tail : 리스트의 첫번째 값을 제외한 나머지 값들의 리스트를 가져옵니다.
  • last : 리스트의 마지막 값을 가져옵니다.
  • init : 리스트의 마지막 값을 제외한 나머지 값들의 리스트를 가져옵니다.

리스트를 몬스터에 비유하면 아래 그림처럼 표현될 수 있습니다.

빈 리스트에는 head, tail, last, init을 사용할 수 없습니다. 이 에러는 컴파일 타임에 잡을 수 없기때문에 위와같은 에러를 대비하는 것이 좋습니다.

length로 리스트의 길이를 얻을 수 있습니다.

null을 사용하여 리스트가 비어있는지 체크할 수 있습니다. null 대신 xs == [] (xs가 리스트 이름이라면..)를 사용해서 체크해도 됩니다.

reverse로 리스트를 뒤집을 수 있습니다.

take로 리스트에서 주어진 개수 만큼만 리스트를 가져올 수 있습니다. 리스트의 크기보다 큰 개수를 요구하면 리스트 전체를 읽어오고, 0을 요구하면 빈 리스트를 반환하는 것을 확인할 수 있습니다.

drop으로 리스트의 앞에서부터 주어진 개수만큼 값을 버릴 수 있습니다.

minimum, mazimum을 사용하여 리스트에서 최소값, 최대값을 가져올 수 있습니다.

sum으로 모든 리스트내 값의 합을 구할 수 있고, product로 모든 값을 곱을 구할 수 있습니다.

elem은 주어진 값이 리스트에 존재하는 값인지를 체크할 수 있습니다. elem은 일반적으로 가독성을 위해 infix 함수(인자를 양옆에 받는 방식)로 사용됩니다.

여기까지 리스트의 기초적인 함수들을 살펴보았습니다. 더 많은 함수는 이후에 다루게 됩니다.

--

--