수정으로 간단한 루프 작성

6487 단어 haskell
fix (Data.Function에 정의됨)은 함수의 최소 고정 소수점을 계산하는 함수입니다.

fix :: (a -> a) -> a
fix f = f (fix f)

예를 들어, 항상 "hello"를 반환하는 함수의 고정 소수점은 다음과 같습니다.

> fix (const "hello")
"hello"

그냥 "안녕하세요". 고정점은 함수의 입력과 출력이 같아지는 지점이기 때문입니다.

재귀 함수는 도메인 이론에서 고차 함수의 최소 고정 소수점으로 쓸 수 있다는 것은 잘 알려져 있습니다.

fact :: Int -> Int
fact = fix $ \f n -> if n == 0 then 1 else n * f (n-1)

수정으로 간단한 루프 작성


fix를 사용하여 일상 생활에서 코드를 작성할 수도 있습니다. 예를 들어 "quit"입력이 수신될 때까지 사용자의 입력을 반전하여 출력하는 동작을 반복하는 프로그램을 구현해 보겠습니다.

main :: IO ()
main = do
    putStrLn "Start"
    fix $ \loop -> do
        str <- getLine
        unless (str == "quit") $ do
            putStrLn (reverse str)
            loop
    putStrLn "Bye"
fix 를 사용하지 않는다면 let 를 사용하여 재귀함수를 한 번 정의한 다음 실행할 수 있지만, Fix를 사용하는 것이 한번에 정의하고 실행할 수 있기 때문에 더 깔끔하다고 생각합니다.

루프에 초기 값 제공



다음으로 루프 수에 대한 제한을 설정하는 예를 살펴보겠습니다. "quit"를 입력하지 않아도 3회 반복하면 자동으로 종료되는 반복문을 만들어 봅시다.

main :: IO ()
main = do
    putStrLn "Start"
    flip fix 3 $ \loop n -> do
        unless (n == 0) $ do
            str <- getLine
            unless (str == "quit") $ do
                putStrLn (reverse str)
                loop (n-1)
    putStrLn "Bye"

수정을 뒤집음으로써 초기 값을 줄 수 있습니다. 아래와 같이 유형에서 확인할 수 있습니다.

> :t flip
flip :: (a -> b -> c) -> b -> a -> c

> :t fix
fix :: (a -> a) -> a

> :t flip fix
flip fix :: b -> ((b -> c) -> b -> c) -> c

즉, fix 유형을 ((b -> c) -> b -> c) -> b -> cflip 로 생각할 수 있습니다.

좋은 웹페이지 즐겨찾기