확장 ScopedTypeVariables

Posted on July 11, 2020

길게 설명할 확장이 아닌 것 같습니다.

함수 서명(선언)의 폴리모픽 타입의 유효 범위scope를 where절까지 확장 할 수 있습니다.

https://wiki.haskell.org/Scoped_type_variables 코드 발췌

{-# LANGUAGE ScopedTypeVariables #-}
mkpair1 :: forall a b. a -> b -> (a,b)
mkpair1 aa bb = (ida aa, bb)
    where
      ida :: a -> a -- 타입 서명의 a와 같은 a입니다.
      ida = id

forall이 있고 없고에 따라 차이를 보면,

mkpair2 :: forall a b. a -> b -> (a,b)
mkpair2 aa bb = (ida aa, bb)
    where
      ida :: b -> b -- 타입 서명의 b와 같은 b이기 때문에 리턴 타입이 달라 오류입니다.
      ida = id

forall이 없으면

mkpair3 :: a -> b -> (a,b)
mkpair3 aa bb = (ida aa, bb)
    where
      ida :: b -> b -- 여기 b는 타입 서명의 b와 전혀 관계 없는 b입니다. b가 뭔지는 GHC가 알아서 추론합니다.
      ida = id

함수 서명에 있는 타입의 유효 범위를 정하기도 하지만, 패턴 매칭할 때 타입을 지정할 필요가 있을 때도 쓰입니다.

{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE FlexibleContexts #-}

import Control.Monad.Reader

func1 :: (MonadIO m, MonadReader Int m) => m ()
--func1 :: m ()
func1 = do
  a :: Int <- ask
  liftIO $ print a

위 예시는 좀 억지스러운데, 아직 실전에서 필요한 경우를 못 만났습니다. 위 a :: Int <- ask 부분은 :: Int가 없어도 컴파일됩니다. 아마도 복잡한 코드에서 명시적으로 타입을 표기하고 싶을 때 쓰지 않을까 싶습니다.


[1] 남현욱님의 ScopedTypeVariables

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