트랙
/
Elm
Elm
/
연습 문제
/
Betty의 자전거 가게
Betty의 자전거 가게

Betty의 자전거 가게

학습 연습 문제

소개

기초 2

함수 내보내기

함수 내보내기는 첫 번째 개념에서 다뤘어요. 여기서 간단히 다시 짚어볼게요.

Elm의 각 파일은 모듈이고, 다른 모든 코드보다 앞에 module문이 있어야 해요.

모듈 이름은 파일 이름과 일치해야 해요. 그래서 Calculator 모듈은 Calculator.elm 파일에, Parser.Utils 모듈은 Parser/Utils.elm 파일에 있어야 하죠.

모듈 안에서 정의한 것은 모두 그 모듈 내부로 범위가 제한돼서, exposing에 나열하지 않는 한 이 모듈 밖에서는 접근할 수 없어요.

-- Calculator.elm
-- Define the Calculator module, and expose the `add` function
module Calculator exposing (add)

six = 3 + 3

add number1 number2 = number1 + number2
-- Calculator.elm
-- Define the Calculator module, and expose everything within: `six` and `add`
module Calculator exposing (..)

six = 3 + 3

add number1 number2 = number1 + number2

https://elm-lang.org/docs/syntax#modules

다른 모듈에서 함수 가져오기

다른 모듈에 정의된 함수에 접근할 때는 가져오기를 사용해요. 그 모듈이 노출한 함수는 모두 그 모듈을 가져올 때 접근할 수 있게 되는데, 어떻게 접근하는지는 모듈을 어떻게 가져오느냐에 따라 달라요.

한정 가져오기가 기본이고, 그런 모듈 안의 함수(예를 들어 List 모듈의 map 함수)에 접근할 때는 모듈 이름을 앞에 붙여요(List.map).

열린 가져오기를 쓰면 그 모듈이 노출한 함수에 접두사 없이 바로 접근할 수 있어요. 내보내기에서 쓴 것과 대칭이 되게 exposing 키워드로 하는데, 사용할 수 있는 함수 전부(..)를 노출할 수도 있고 특정 함수(예를 들어 map)만 노출할 수도 있어요.

다른 모듈에서 타입과 그 생성자를 가져올 수도 있는데, 이건 나중 개념이에요.

명확성을 높이고 이름 충돌을 피하기 위해 한정 가져오기를 권장해요.

-- qualified imports
import List                            -- List.map, List.foldl
import List as L                       -- L.map, L.foldl

-- open imports
import List exposing (..)              -- map, foldl, concat, ...
import List exposing ( map, foldl )    -- map, foldl, List.concat

https://elm-lang.org/docs/syntax#modules

타입 애너테이션

타입 애너테이션은 name : parameter types -> return type처럼 정의하고, 매개변수 타입들도 ->로 구분해요.

add : Int -> Int -> Int
add number1 number2 = number1 + number2

괄호를 써서 함수 매개변수를 정의할 수 있는데, 매개변수 자체도 같은 문법으로 정의되기 때문에 괄호가 필요해요.

-- Transform every character in a string
map : (Char -> Char) -> String -> String
map charMapperFunction string =
    -- ...

https://elm-lang.org/docs/syntax#type-annotations

숫자

Elm에서 쓸 수 있는 숫자에는 두 가지 타입이 있어요. Int와 Float 타입으로 정의되죠. Int는 양의 정수와 음의 정수의 집합에 해당해요. Float는 실수의 집합에 해당하는데, 컴퓨터의 정밀도에 따라 한계가 있어요. 숫자에 정의된 연산은 보통 둘 중 한 타입에서만 동작하고, 두 타입을 섞지는 못해요. 둘 사이를 변환하는 함수도 있는데, toFloat는 Int를 Float로 바꾸고, round, floor, ceiling, truncate는 각기 다른 방식으로 Float를 Int로 바꿔요.

https://package.elm-lang.org/packages/elm/core/latest/Basics#Int

문자열 연산

코드에서 단어와 문장을 표현하려고 Elm에는 String이라는 기본 제공 타입이 있어요. 문자열 리터럴은 "Hello World!"처럼 큰따옴표 사이에 써요. 문자열 연결 연산자 ++와 동등 연산자 ==를 기본으로 쓸 수 있어요.

hello : String -> String
hello subject = "Hello " ++ subject

hello "World!" --> "Hello World!"

나머지 문자열 함수는 대부분 String 모듈에 있고, 이 모듈은 가져와야 해요.

https://package.elm-lang.org/packages/elm/core/latest/String

지침

이번 연습 문제에서는 자전거와 부품을 파는 온라인 상점인 Betty's Bike Shop을 돕는 코드를 작성해요. 웹사이트에 자전거와 부품 가격을 올바르게 표시하는 것을 목표로 하는 세 가지 작업이 있어요.

1. penceToPounds 함수 내보내기

동료가 이미 모듈의 뼈대, 즉 아직 정의되지 않은 penceToPounds 함수와 poundsToString 함수를 작성해 두었어요. 하지만 penceToPounds 함수를 내보내는 것을 잊어버렸기 때문에, 지금은 다른 모듈이나 테스트 스위트에서 이 함수를 볼 수 없어요.

내보내는 함수 목록에 penceToPounds를 추가해요.

2. 펜스를 파운드로 변환하기

현재 가격은 펜스 단위의 정수로 저장되어 있어요(이 자전거 가게는 영국에 있어요). 웹사이트에서는 가격을 파운드로 표시하려고 해요. 여기서 1.00파운드는 100펜스예요. 두 번째 작업은 penceToPounds 함수를 구현하는 거예요. 이 함수는 펜스 금액을 Int로 받아서, 그에 해당하는 파운드 값을 Float로 변환해요. 이 함수의 타입 애노테이션도 정의해야 해요.

penceToPounds 106
    --> 1.06

3. 웹사이트에 표시할 가격 형식 지정하기

Betty's bikes는 파운드로 판매되기 때문에, 가격은 "£" 기호와 함께 표시되어야 해요. 따라서 세 번째 작업은 poundsToString 함수를 구현하는 거예요. 이 함수는 파운드 금액을 Float로 받아서, 앞에 파운드 기호를 붙인 가격을 String으로 반환해요. String 모듈에는 이 작업에 도움이 될 String.fromFloat 함수가 있어요. String 모듈은 사용하기 전에 먼저 import 해야 해요. poundsToString의 타입 애노테이션도 정의해야 해요.

poundsToString 1.06
    --> "£1.06"
GitHub에서 편집 링크가 새 창이나 탭에서 열려요
Elm Exercism

Betty의 자전거 가게 문제를 시작해 볼 준비가 됐나요?

Exercism에 가입하고 Elm 트랙을 개념 28개연습 문제 110개, 그리고 실제 사람의 멘토링과 함께 배우고 익혀 보세요. 모두 무료예요.