OverloadedStrings - schoolofhaskell
schoolofhaskell에서 서광열님 글을 만나니 반갑네요. 위 링크에 짧고 간결하게 설명되어 있습니다.
GHC는 소스에서 리터럴 “Hello World” 를 만나면 기본 String
([Char]
)으로 인식합니다. 하지만 하스켈에는 문자열 타입으로 Text
, ByteString
도 있습니다. 리터럴로 바로 Text
, ByteString
타입을 만들려면 필요한 확장입니다.
OverloadedStrings 확장을 켜지 않으면 리터럴은 String
타입,
OverloadedStrings 확장을 켜면 리터럴은 IsString a => a
타입입니다.
하나의 구체 타입이 아닙니다. a
는 IsString
의 인스턴스이기만 하면 모두 ok입니다. Text
도, ByteString
도 모두 IsString
의 인스턴스이기 때문에 리터럴은 String
, Text
, ByteString
모두 될 수 있다는 얘기입니다.
리터럴만 보고는 구체 타입을 결정할 수 없습니다. 타입 서명이나 조립된 코드들을 보고 GHC가 추론하게 됩니다. 참고로 GHCi에서 테스트 하려면 디폴트가 OverloadedStrings 확장을 켠 상태이므로 끄려면 :set -XNoOverloadedStrings
확장을 켜야 합니다.
{-# LANGUAGE OverloadedStrings #-}
import Data.Text
= "Hello World" a
a
의 타입은 구체 타입이 아니라 IsString a => a
타입입니다. “구체 타입은 나중에 상황봐서 결정할게”라는 얘기입니다.
a :: Text
= "Hello World" a
이렇게 타입 서명에서 명시적으로 지정해 주면 a
는 Text
타입으로 추론됩니다.
func :: Text -> IO ()
= putStrLn "ok"
func t
> func "Hello World"
코드를 조립하며 만난 func
함수의 타입을 보고 리터럴 "Hello World"
를 Text
타입으로 추론합니다. 확장이 꺼져 있으면 에러가 납니다.
Couldn't match expected type ‘Text’ with actual type ‘[Char]’