하나의 값에 다수의 값을 저장한다는 측면에서 튜플은 리스트와 유사하다. 하지만 몇 가지 근본적인 차이점이 있다. 숫자의 리스트는 숫자의 리스트일 뿐이다. 그 자체가 타입이고 하나의 숫자만 갖느냐 아니면 무한개의 숫자를 갖느냐는 아무런 문제가 되지 않는다.
하지만 튜플은 결합시킬 값의 갯수를 정확히 알고 있을 때 사용할 수 있다. 얼마나 많은 요소를 포함하고 있고 그 요소의 타입이 무엇인지에 따라 타입 또한 결정된다. 튜플은 괄호로 표시되고 구성요소는 콤마로 구분된다.
다른 주요한 차이점은 구성요소들이 동질(homogenous)의 것일 필요는 없다는 것이다. 리스트와 다르게 튜플은 다양한 타입의 요소를 포함할 수 있다.
하스켈에서 2차원의 벡터를 어떻게 나타낼 수 있을지 생각해보자. 하나의 방법은 리스트를 사용하는 것이다. 그렇다면 2차원의 비행기 형상의 지점을 나타내기 위해 다수의 벡터를 리스트에 넣고자하면 어떨까? [[1,2],[8,11],[4,5]]와 같이 할 수 있을 것이다.
하지만 위의 방식의 문제점은 [[1,2],[8,11,5],[4,5]]와 같은 리스트도 가능하다는 것인데, 앞의 예를 적용하자면 이건 말이 안된다는 것이다(물론 리스트를 원소로 갖는 리스트이므로 이 자체는 문제가 없다). 하지만 흔히 pair 이라고 불리는 크기가 2인 튜플은 그 자체로 타입이 되는데, 이 말은 크기가 3인 튜플은 포함될 수 없다는 것이다. 표시는 괄호를 이용하여 [(1,2),(8,11),(4,5)]와 같이 표현하면 된다. 만약 [(1,2),(8,11,5),(4,5)] 를 입력하면 다음과 같은 에러가 발생한다. 같은 리스트에 페어와 트리플을 함께 넣을 수 없다는 것이다.
- Prelude> [(1,2),(8,11),(4,5)]
- [(1,2),(8,11),(4,5)]
- Prelude> [(1,2),(8,11,5),(4,5)]
- • Couldn't match expected type ‘(t1, t)’
- • In the expression: (8, 11, 5)
- In the expression: [(1, 2), (8, 11, 5), (4, 5)]
- In an equation for ‘it’: it = [(1, 2), (8, 11, 5), (4, 5)]
- • Relevant bindings include
- it :: [(t1, t)] (bound at <interactive>:20:2)
리스트와 마찬가지로 구성요소끼리 비교가 가능하다면 튜플 역시 비교가 가능하다. 서로 다른 크기의 2개의 리스트는 비교가 가능하지만, 크기가 서로 다른 2개의 튜플은 비교할 수 없다. 페어를 조작하는데 도움이 되는 2개의 함수는 다음과 같다.
fst 는 페어를 받아서 첫번째 요소를 반환한다.
- 8
- "Wow"
snd 는 페어를 받아 두번째 요소를 반환한다.
- 11
- False
다만, 위의 함수들은 페어에만 적용된다. triples, 4-tuples, 5-tuples 등을 다루는 방법은 이후에 설명한다.
페어 리스트에 적용할 수 있는 또 다른 함수로 zip이 있다. 2개의 리스트를 받아 매칭되는 원소끼리 조인을 시켜 페어 리스트로 만든다. 2개의 리스트를 결합하거나 2개의 리스트를 동시에 횡단할 때 유용하다. 첫 번째 요소는 첫 번째 요소와 두 번째 요소는 두 번째 요소와 페어링해서 새로운 리스트를 만들어낸다.
- [(1,5),(2,5),(3,5),(4,5),(5,5)]
- Prelude>
- [(1,"one"),(2,"two"),(3,"three"),(4,"four"),(5,"five")]
- Prelude>
만약 리스트의 길이가 맞지 않으면 어떻게 될까? 길이를 맞추기 위해 짧은 리스트의 길이에 맞춰 컷팅된다.
- [(5,"im"),(3,"a"),(2,"turtle")]
그리고 하스켈은 lazy 하므로,무한 리스트와 유한 리스트를 zip 할 수 있다.
- [(1,"apple"),(2,"orange"),(3,"cherry"),(4,"mango")]
각 변의 길이가 10이하이고, 둘레가 24인 삼각형을 찾는 문제를 풀어보자.
1) 각 변의 길이가 1에서 10인 모든 삼각형의 조합을 찾는다.
2) 세 변의 길이가 삼각형의 공식에 부합하는 경우만 찾아낸다.
3) 마지막으로 둘레의 합이 24인 경우를 찾는다.
- Prelude> triangles = [ (a,b,c) | c <- [1..10], b <- [1..10], a <- [1..10] ]
- Prelude> rightTriangles = [ (a,b,c) | c <- [1..10], b <- [1..c], a <- [1..b], a^2 + b^2 == c^2]
- Prelude> rightTriangles' = [ (a,b,c) | c <- [1..10], b <- [1..c], a <- [1..b], a^2 + b^2 == c^2, a+b+c == 24]
- Prelude> rightTriangles'
- [(6,8,10)]
'프로그래밍 Programming' 카테고리의 다른 글
하스켈 Starting out - (8) 타입 (0) | 2017.12.05 |
---|---|
Error haskell: Variable not in scope (0) | 2017.12.04 |
하스켈 Starting out - (6) list comprehension (0) | 2017.12.02 |
ghci, stack ghci 버전 확인하기 (0) | 2017.12.02 |
하스켈 Starting out - (5) range, cycle, repeat, replicate 함수 (0) | 2017.12.02 |