체질량지수는 자신의 몸무게를 키의 제곱으로 나눈 값이다. 몸무게 단위는 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;
하스켈로 함수 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
아하m
은cm
를 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
- 그 다음에 파이프
|
를 적은 뒤 검사하고 싶은 조건을 적는다. - 등호
=
를 적고 왼쪽에 적은 조건이 참인 경우 리턴할 값을 적으면 된다.
키워드 otherwise
는 True
와 같은 값이다.
가드의 마지막 조건에 otherwise
를 적어주면 안전한 함수를 만들 수 있다. else
와 비슷한 역할을 한다. otherwise
를 적지 않는다고 해서 컴파일 에러가 나지는 않는다.