https://wiki.haskell.org/Lazy_pattern_match
문법
let (a,b) = p -- 이 경우만 ~가 없어도 lazy 패턴 매칭
~p = ...
func case p of ~(a,b) -> ...
~(a,b) -> ...) (\
틸드 ~ 를 패턴에 붙여주면, 나중에 필요할 때 매칭합니다. 보통 패턴 매칭과 비교하면,
= ... -- 튜플 생성자와 바로 매칭
func (a,b) ~(a,b) = ... -- 바로 튜플과 매칭하는게 아니라, 나중에 body에서 필요할 때 매칭 func
~(a,b) = g a b
func -- 이렇게 쓴 건 아래와 같은 의미
= g (fst p) (snd p) func p
p
는 바로 튜플로 매칭하지 않고 있다가, fst
를 만나면 튜플로 매칭합니다.
주의
func :: [a] -> [a]
~(x:xs) = x:xs
func = [] func []
Lazy 패턴을 먼저 매칭하면 두 번째 나온 빈 리스트도 Lazy 패턴에서 매칭되므로 마지막 []
패턴일 때 정의가 필요 없다는 경고가 나옵니다.
~(x:xs) = x:xs
func -- 위 패턴을 접근자accessor 로 풀어 쓰면
= head p : tail p func p
빈 리스트 검사를 하지 않은 상태에서 head
와 tail
에 넘겨지므로 위험한 모양이 됩니다.
아마도 Lazy 패턴은 퍼포먼스가 필요할 때 쓸 것 같습니다. 두 개 이상의 값 생성자를 가진 타입과 Lazy 패턴 매칭을 하는 건 피하는게 좋다고 합니다.