Haskell의 지수 함수들

2020-05-29, Fri

하스켈은 여러 종류의 지수 함수를 가지고 있다.

^, ^^, ** 이렇게 3개가 있는데 전부 역할이 다르다.

main :: IO ()
main = do
  -- (^) :: (Integral b, Num a) => a -> b -> a
  print $ (2 :: Int) ^ (3 :: Int)               -- 8 :: Int
  print $ (2 :: Int) ^ (-3 :: Int)              -- *** Exception: Negative exponent
  print $ (-2 :: Int) ^ (3 :: Int)              -- -8 :: Int
  print $ (-2 :: Int) ^ (-3 :: Int)             -- *** Exception: Negative exponent
  print $ (2.5 :: Double) ^ (3 :: Int)          -- 15.625 :: Double
  print $ (-2.5 :: Double) ^ (3 :: Int)         -- -15.625 :: Double
  print $ (-2.5 :: Double) ^ (3 :: Integer)     -- -15.625 :: Double
  print $ (-2.5 :: Float) ^ (3 :: Int)          -- -15.625 :: Float

  -- (^^) :: (Fractional a, Integral b) => a -> b -> a
  print $ (2.5 :: Double) ^^ (3 :: Int)         -- 15.625 :: Double
  print $ (-2.5 :: Double) ^^ (3 :: Int)        -- -15.625 :: Double
  print $ (2.5 :: Double) ^^ (-3 :: Int)        -- 6.4e-2 :: Double
  print $ (-2.5 :: Double) ^^ (-3 :: Int)       -- -6.4e-2 :: Double
  print $ (-2.5 :: Double) ^^ (-3 :: Integer)   -- -6.4e-2 :: Double

-- (**) :: Floating a => a -> a -> a
  print $ (2.5 :: Double) ** (3.5 :: Double)    -- 24.705294220065465 :: Double
  print $ (-2.5 :: Double) ** (-3 :: Double)    -- -6.4e-2 :: Double
  print $ (-2.5 :: Double) ** (-3.5 :: Double)  -- NaN

Num, Integral, Fractional, Floating이 무엇인지는 Wikibooks Haskell에 소개가 되어 있다. 진행중이긴 하지만 한국어 번역본도 있다.

이렇게 여러 종류의 지수 함수가 있는 이유는 하스켈 위키에 설명되어 있다.

Type Promotion이 일어나지 않기 때문에 다른 언어에서 처럼 사용하면 컴파일 에러가 발생한다. fromIntegral을 활용해 타입을 맞춰주어야 한다.

특별히 주의할 점으로는 ^의 경우 음수 지수를 계산하면 Exception이 발생한다. Partial function 인데 하스켈은 unsinged 타입을 잘 활용하지 않으니 어쩔 수 없이 사람이 조심해야 한다.