Relude 살펴보기

Eunmin Kim·2022년 6월 5일
2

하스켈 일기

목록 보기
4/12

오늘은 노는 날이니 짧게 쓰자. 요즘 하스켈 사용하면서 가장 많이 보이는 것이 많은 프로젝트에서 Prelude 대신 Relude를 사용한다는 점이다. Relude의 목표 중 하나가 생산성이기 때문에 팀원 분들에게 소개하고 프로젝트에 도입할 수 있을지 고민해보려고 한다. 지난번에도 언급한 Practical Web Development with Haskell에도 Prelude 대신 ClassyPrelude라고 하는 패키지를 사용하는 것을 보니 실용적인 서비스에서 대체로 Prelude 대신 사용하는 패키지를 사용하는 것 같다.
Relude는 하스켈 스타일 가이드로 검색했을 때 가장 먼저 나왔던 Kowainik이라고 하는 팀에서 만든 프로젝트이다.
문서도 잘 정리되어 있어 문서를 가볍게(아는 것만) 읽어보고 어떤 좋은 점이 있는지 살펴보자.
문서에 Relude를 프로젝트에 사용하는 방법이 여러 가지 나와 있지만 가장 쉬워 보이는 NoImplicitPrelude 언어 확장을 사용하는 방법으로 stack 프로젝트를 만들어 확인해보자.
package.yamlrelude 패키지 의존성을 추가하고 default-extensionsNoImplicitPrelude를 추가하자.

default-extensions: 
  - NoImplicitPrelude

stack이 기본으로 만들어 준 템플릿에서 Relude 기능을 몇 가지 확인해보자. 별 것은 아니지만 Prelude를 다시 만든 패키지에서 가장 쓸모 있어 보이는 기능은 자주 사용하는 패키지를 Reexport 한 것이다. 그래서 Reludeimport해도 다음 패키지에 있는 각종 모듈을 바로 쓸 수 있다.

base
bytestring
containers
deepseq
ghc-prim
hashable
mtl
stm
text
transformers
unordered-containers

특히 mtl, transformers, text, containers 같은 것은 자주 쓰고 있는데 Text나 각종 모나드 트랜스포머 같은 것을 따로따로 import하지 않고 써도 돼서 편리하다.
아마 탐구하는 대로 일기에 적으려고 하지만 deepseq 패키지도 reexport되어 있다. 최근 하스켈 strictlazy에 대한 이해 부족 때문에 중첩된 데이터 구조에서 발생하는 예외를 테스트 코드에서 못 잡고 있었는데 아마도 지금 있는 데이터 구조에 NFData 인스턴스를 만들고 강제로 evaluation하면 될 것으로 추측하고 있다.
두 번째로 undefined가 있는 부분이 컴파일러 warning처리되어 있다는 점이다. 하스켈은 타입을 먼저 작성하는 경우가 많아 구현을 undefined로 남겨두는 경우가 많은데 실수로 구현을 깜빡하는 것을 예방해줄 수 있을 것 같다. 다음은 지금 쓰고 있는 VSCode 하스켈 확장을 설치하고 Reludeimport하고 undefined를 사용해 본모습이다.

또 몇 가지 눈에 들어오는 점은 head, tail, init, last와 같은 리스트 함수가 빈 리스트일 때 예외가 발생하는데 안전을 위해 기본으로 빈 리스트에 쓸 수 없도록 하는 버전을 써야 한다.

head :: NonEmpty a -> a    -- the first element of the list
tail :: NonEmpty a -> [a]  -- the list without the first element
last :: NonEmpty a -> a    -- the last element of the list
init :: NonEmpty a -> [a]  -- the list without the last element

안전을 위한 기능은 몇 가지 또 있는데 read도 타입 변환에 실패하면 역시 예외가 발생하는데 read를 기본으로 쓸 수 없고 대신 readMaybe를 기본으로 쓸 수 있다.

-- >>> readMaybe "1" :: Maybe Int
-- Just 1

그 외에도 sum이나 product 함수를 strict 버전으로 쓰도록 해서 메모리 사용량을 줄이거나 error 함수가 Text를 받을 수 있게 하는 버전(String 대신 Text를 사용하는 것을 권장)등 여러 가지 유용한 기능이 있는 것 같다.
지금은 reexport 기능으로도 충분히 코드 크기를 줄일 수 있을 것 같아서 프로젝트에 도입해보자고 해야겠다.

profile
Functional Programmer @Constacts, Inc.

0개의 댓글