Skip to content

Instantly share code, notes, and snippets.

@nattybear
Last active January 1, 2021 06:47
Show Gist options
  • Save nattybear/630186d4a332a8da3eab9a55641045e0 to your computer and use it in GitHub Desktop.
Save nattybear/630186d4a332a8da3eab9a55641045e0 to your computer and use it in GitHub Desktop.
하스켈 where와 guard

BMI

체질량지수는 자신의 몸무게를 키의 제곱으로 나눈 값이다. 몸무게 단위는 kg이고 키 단위는 m이다. Body Mass Index

float bmi(float kg, float cm)
{
  float m = cm / 100;
  return kg / (m * m);
}

우리나라에서는 사람 키를 표현할 때 단위로 cm를 사용한다. 그런데 BMI는 키 단위로 m를 사용하기 때문에 변환을 해야 한다.

float m = cm / 100;

where

하스켈로 함수 bmi를 구현해보자.

bmi :: Float -> Float -> Float
bmi kg cm = kg / m^2
  where m = cm / 100

하스켈에서는 where을 이용해 함수 안에서 새로운 변수 이름을 정의할 수 있다.

C언어에서는 변수 m을 사용하기 전에 먼저 정의를 해야하지만

하스켈에서 where는 나중에 적는다.

먼저 C언어 코드를 읽는 사람 의식의 흐름은 아래와 같다.

먼저 변수 m을 선언하고 여기에 cm을 변환한 값을 할당하는구나. m = cm / 100
그 다음에 m을 제곱하고 그것으로 kg을 나누네. kg / (m * m)

사람도 기계도 코드를 적은 순서대로 해석한다.

반면에 하스켈러 의식의 흐름은 아래와 같다.

m을 제곱한 값으로 kg을 나누는구나. 어라? 그런데 m은 갑자기 어디서 나왔지? kg / m^2
아하 mcm를 100으로 나눈 값이구나. where m = cm / 100

여러가지 경우

대한비만학회 비만 진료지침에 따르면 BMI 기준은 아래와 같다.

  • 23 ~ 24.9 : 비만 전 단계
  • 25 ~ 29.9 : 1단계 비만
  • 30 ~ 34.9 : 2단계 비만
  • 35 이상 : 고도 비만

BMI 값을 넣으면 비만 여부를 알려주는 함수 amIFat을 C++로 쓰면 아래와 같다.

string amIFat(float bmi)
{
  if (23 <= bmi && bmi < 25)
    return "비만 전 단계";
  else if (25 <= bmi && bmi < 30)
    return "1단계 비만";
  else if (30 <= bmi && bmi < 35)
    return "2단계 비만";
  else
    return "고도 비만";
}

C++에서는 조건에 따른 분기를 할 때 if, else if, else 키워드를 사용한다.

하스켈에도 if가 있기는 하지만 한번에 조건 하나만 검사할 수 있다. 하스켈에는 else if 같은 키워드가 없다.

하스켈에는 guard라는 기능이 있다.

함수 amIFat을 하스켈로 쓰면 아래와 같다.

amIFat :: Float -> String
amIFat bmi
  | 23 <= bmi && bmi < 25 = "과체중"
  | 25 <= bmi && bmi < 30 = "1단계 비만"
  | 30 <= bmi && bmi < 35 = "2단계 비만"
  | otherwise             = "고도 비만"
  • 다른 함수와 마찬가지로 먼저 함수 이름과 인자를 적고 amIFat bmi
  • 그 다음에 파이프 |를 적은 뒤 검사하고 싶은 조건을 적는다.
  • 등호 =를 적고 왼쪽에 적은 조건이 참인 경우 리턴할 값을 적으면 된다.

키워드 otherwiseTrue와 같은 값이다.

가드의 마지막 조건에 otherwise를 적어주면 안전한 함수를 만들 수 있다. else와 비슷한 역할을 한다. otherwise를 적지 않는다고 해서 컴파일 에러가 나지는 않는다.

진짜 쉬운 하스켈

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment