2017-09-19 4 views
1
fac n = if n < 2 then 1 else n * fac (n-1) 

main = do 

    putStrLn "Enter a number: " 
    number <- getLine 
    print $ number >>= fac 

if 문없이 재귀 적 계승 함수를 작성하는 법을 모르겠습니다. 우리 교수는 람다 미적분학에 관한 한 가지 언급을했습니다.if then else statue없이 회귀 적 계승 함수를 쓰는 법

+2

https://en.wikibooks.org/wiki/Haskell/Pattern_matching – Ryan

+0

[뺨 않음 혀 (https://www.willamette.edu/~fruehr/haskell/ evolution.html) – gallais

답변

5

패턴 일치 및 보호는 두 가지 방법으로 특히 간단합니다. Guard는 본질적으로 if-then-else의 또 다른 구문입니다. 그들은 다음과 같이 보입니다 :

fac n | n < 2  = 1 
     | otherwise = n * fac (n-1) 

if-then-else와 달리, 여러 조건을 완벽하게 지원합니다. 예를 들어,

fac n | n < 0 = error "nah" 
     | n == 0 = 1 
     | n == 1 = 1 
     | n > 1 = n * fac (n-1) 

과 같이 작성할 수 있습니다.이 경우 if-then-else 형식이 훨씬 더 어둡습니다. 패턴 매칭

하나는 일반적으로 다수의 정의 방정식을 작성 :

특정의 수치
fac 0 = 1 
fac 1 = 1 
fac n = n * fac (n-1) 

, 이것은 또한 desugars에 본질적 IF-그때 다른; 그러나 컴파일러 통합이 적은 데이터 유형의 경우 종종 if-then-else로 에뮬레이션 될 수 없으며 종종 매우 자연스러운 코드로 이어집니다.

또 다른 멋진 접근법은 기존 Prelude 함수로 재귀를 푸는 것입니다. 실제로 반복 패턴을 발견할수록 동일한 루프를 반복해서 반복하지 않아야하는 버그를 피할 수 있습니다. 이 일을 위해, 당신은 product 및 특수 열거 구문을 사용할 수 있습니다 : 기술은 수의 새로운 종류를 정의하는 것입니다

fac n = product [1..n] 

더 고급 (크게 악화) 예 : 교회 숫자는 숫자의 생산자가 재귀를 일으키는 것을 허용하고, 소비자 (여기, fac)는 기초 사례를 제공합니다. 이 스타일에서는 다음과 같이 표시 될 수 있습니다

fac n = fst (n (1,1) (\(prod, sum) -> (prod*sum, sum+1))) 

을 (그러나 이것은 수의 아주 특별한 종류의 필요로 충분히주의 - 확실히 fac의 유형을 수용 할 수있는 기능 중 하나가 아닌를 Int 또는 Integer !)이 농담은 The Evolution of a Haskell Programmer의 논리적이고 끔찍한 결론에 도달했습니다.

+0

'(==)'에서'Bool'에 패턴 매칭을 잊지 마라. 이것은 경비원과 if/then/else가 모두 설탕이되는 이유이다. (하스켈은 너무 많은 특별한 방법으로 처리 할 수있다. Bool) – Carl

1

/then/else와 guard는 실제로 패턴 일치를위한 문법적 설탕 일뿐입니다.

case b of 
    True -> c 
    False -> d 

유사에

if b 
    then c 
    else d 

desugars,

f x = case b of 
     True -> c 
     False -> case d of 
      True -> e 
      False = g 

f x 
    | b = c 
    | d = e 
f x = g 

desugars 그래서 당신은 항상 직접 case를 사용할 수 있습니다. 그러나 손으로 수행 할 수있는 간단한 최적화가 있습니다.

factorial 0 = 1 
factorial n = n * factorial (n - 1) 

사용 꼬리 재귀 : 당신이 p이 생성자와 리터럴 구성되어

case x == p of 
    True -> a 
    False -> b 

를 볼 경우이 시도

case x of 
    p -> a 
    _ -> b 
1

로 전체를 교체 할 수 있습니다 :

,210

출력 :

120