갈루아의 반서재

Range 함수는 숫자, 알파벳 등 셀수 있는 원소들을 산술적으로 나열할 때 유용하게 쓰인다. 예를 들어, 1에서 20까지 모든 자연수를 포함하는 리스트를 만들려면 [1..20]라고 작성하면 된다. 물론[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20] 와 같이 작성해도 똑같으나 이건 멍청한 방법이다. 

  1. Prelude> [1..20]
  2. [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20]
  3. Prelude> ['a'..'z']
  4. "abcdefghijklmnopqrstuvwxyz"
  5. Prelude> ['K'..'Z']
  6. "KLMNOPQRSTUVWXYZ"
  7. Prelude>

그러면 1과 20 사이에 있는 짝수로 이루어진 리스트는 어떻게 만들 수 있는가? 또는 1과 20사이에 있는 3번째 숫자만으로 이루어진 리스트는 어떻게 만들 수 있을까?

  1. Prelude> [2,4..20]
  2. [2,4,6,8,10,12,14,16,18,20]
  3. Prelude> [3,6..20]
  4. [3,6,9,12,15,18]
  5. Prelude>

간단하다. 첫 2개의 원소를 콤마로 구분해주고 마지막에 상한을 지정하면 된다. 그러면 20에서 시작하여 1로 끝나는 리스트는 어떻게 만들수 있을까? 이 경우에는 [20..1]이 아니라 [20,19..1]로 만들 수 있다.

  1. Prelude> [20..1]
  2. []
  3. Prelude> [20,19..1]
  4. [20,19,18,17,16,15,14,13,12,11,10,9,8,7,6,5,4,3,2,1]

실수의 경우, 정의상 실수 자체가 정밀하지 못하기 때문에 다음과 같은 기괴한 결과가 나온다. 

  1. Prelude> [0.10.3 .. 1]
  2. [0.1,0.3,0.5,0.7,0.8999999999999999,1.0999999999999999]
  3. Prelude>

상위값을 설정하지 않음으로써 무한 리스트를 만들 수도 있다. 추후에 이 부분에 대해서는 자세히 살펴보고 일단은 13배의 배수 24개를 포함한 리스트를 만들어보자.

  1. relude> [13,26..13*24]
  2. [13,26,39,52,65,78,91,104,117,130,143,156,169,182,195,208,221,234,247,260,273,286,299,312]
  3. Prelude> take 24 [13,26..]
  4. [13,26,39,52,65,78,91,104,117,130,143,156,169,182,195,208,221,234,247,260,273,286,299,312]

[13,26..24*13]도 가능하지만 더 좋은 방법이 있다. 바로 take 24 [13,26..] 이다. 하스켈은 근본적으로 LAZY 하기 때문에, 무한 리스트를 즉시 평가하려고 하지 않는다. 왜냐하면 끝이 나지 않기 때문이다. 그 무한리스트에서 무엇을 얻어낼 것인지를 기다릴 것이다. 그리고 여기서 보는대로 호출할 갯수가 정해지면 즉각 움직인다.

무한리스트를 생성하는 간단한 함수를 살펴보자. cycle 함수는 리스트를 받아서 무한 리스트를 생성한다. 

  1. Prelude> take 10 (cycle[1,2,3])
  2. [1,2,3,1,2,3,1,2,3,1]
  3. Prelude> take 12 (cycle "LOL")
  4. "LOLLOLLOLLOL"

이에 반해 repeat는 하나의 원소를 무한 반복한다. 

  1. Prelude> take 10 (repeat 5)
  2. [5,5,5,5,5,5,5,5,5,5]

만약 10을 3번만 반복하기 원한다면 다음과 같이 할 수 있다/

  1. Prelude> replicate 3 10
  2. [10,10,10]