Lazy Pattern Match

Posted on July 11, 2020

https://wiki.haskell.org/Lazy_pattern_match

문법

let (a,b) = p -- 이 경우만 ~가 없어도 lazy 패턴 매칭
func ~p = ...
case p of ~(a,b) -> ...
(\~(a,b) -> ...)

틸드 ~ 를 패턴에 붙여주면, 나중에 필요할 때 매칭합니다. 보통 패턴 매칭과 비교하면,

func (a,b) = ... -- 튜플 생성자와 바로 매칭
func ~(a,b) = ... -- 바로 튜플과 매칭하는게 아니라, 나중에 body에서 필요할 때 매칭
func ~(a,b) = g a b
-- 이렇게 쓴 건 아래와 같은 의미
func p = g (fst p) (snd p)

p는 바로 튜플로 매칭하지 않고 있다가, fst를 만나면 튜플로 매칭합니다.

주의

func :: [a] -> [a]
func ~(x:xs) = x:xs
func [] = []

Lazy 패턴을 먼저 매칭하면 두 번째 나온 빈 리스트도 Lazy 패턴에서 매칭되므로 마지막 [] 패턴일 때 정의가 필요 없다는 경고가 나옵니다.

func ~(x:xs) = x:xs
-- 위 패턴을 접근자accessor 로 풀어 쓰면
func p = head p : tail p

빈 리스트 검사를 하지 않은 상태에서 headtail에 넘겨지므로 위험한 모양이 됩니다.

아마도 Lazy 패턴은 퍼포먼스가 필요할 때 쓸 것 같습니다. 두 개 이상의 값 생성자를 가진 타입과 Lazy 패턴 매칭을 하는 건 피하는게 좋다고 합니다.

Github 계정이 없는 분은 메일로 보내주세요. lionhairdino at gmail.com