길게 설명할 확장이 아닌 것 같습니다.
함수 서명(선언)의 폴리모픽 타입의 유효 범위scope를 where
절까지 확장 할 수 있습니다.
https://wiki.haskell.org/Scoped_type_variables 코드 발췌
{-# LANGUAGE ScopedTypeVariables #-}
mkpair1 :: forall a b. a -> b -> (a,b)
= (ida aa, bb)
mkpair1 aa bb where
ida :: a -> a -- 타입 서명의 a와 같은 a입니다.
= id ida
forall
이 있고 없고에 따라 차이를 보면,
mkpair2 :: forall a b. a -> b -> (a,b)
= (ida aa, bb)
mkpair2 aa bb where
ida :: b -> b -- 타입 서명의 b와 같은 b이기 때문에 리턴 타입이 달라 오류입니다.
= id ida
forall
이 없으면
mkpair3 :: a -> b -> (a,b)
= (ida aa, bb)
mkpair3 aa bb where
ida :: b -> b -- 여기 b는 타입 서명의 b와 전혀 관계 없는 b입니다. b가 뭔지는 GHC가 알아서 추론합니다.
= id ida
함수 서명에 있는 타입의 유효 범위를 정하기도 하지만, 패턴 매칭할 때 타입을 지정할 필요가 있을 때도 쓰입니다.
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE FlexibleContexts #-}
import Control.Monad.Reader
func1 :: (MonadIO m, MonadReader Int m) => m ()
--func1 :: m ()
= do
func1 a :: Int <- ask
$ print a liftIO
위 예시는 좀 억지스러운데, 아직 실전에서 필요한 경우를 못 만났습니다. 위 a :: Int <- ask
부분은 :: Int
가 없어도 컴파일됩니다. 아마도 복잡한 코드에서 명시적으로 타입을 표기하고 싶을 때 쓰지 않을까 싶습니다.