확장 OverloadedStrings

Posted on July 29, 2020

OverloadedStrings - schoolofhaskell
schoolofhaskell에서 서광열님 글을 만나니 반갑네요. 위 링크에 짧고 간결하게 설명되어 있습니다.

기본은 String 타입

GHC는 소스에서 리터럴 “Hello World” 를 만나면 기본 String([Char])으로 인식합니다. 하지만 하스켈에는 문자열 타입으로 Text, ByteString도 있습니다. 리터럴로 바로 Text, ByteString 타입을 만들려면 필요한 확장입니다.

OverloadedStrings 확장을 켜지 않으면 리터럴은 String 타입,
OverloadedStrings 확장을 켜면 리터럴은 IsString a => a 타입입니다.

IsString a => a 타입

하나의 구체 타입이 아닙니다. aIsString의 인스턴스이기만 하면 모두 ok입니다. Text도, ByteString도 모두 IsString의 인스턴스이기 때문에 리터럴은 String, Text, ByteString 모두 될 수 있다는 얘기입니다.

타입 추론

리터럴만 보고는 구체 타입을 결정할 수 없습니다. 타입 서명이나 조립된 코드들을 보고 GHC가 추론하게 됩니다. 참고로 GHCi에서 테스트 하려면 디폴트가 OverloadedStrings 확장을 켠 상태이므로 끄려면 :set -XNoOverloadedStrings 확장을 켜야 합니다.

{-# LANGUAGE OverloadedStrings #-}
import Data.Text

a = "Hello World"

a의 타입은 구체 타입이 아니라 IsString a => a 타입입니다. “구체 타입은 나중에 상황봐서 결정할게”라는 얘기입니다.

a :: Text
a = "Hello World"

이렇게 타입 서명에서 명시적으로 지정해 주면 aText 타입으로 추론됩니다.

func :: Text -> IO ()
func t = putStrLn "ok"

> func "Hello World"

코드를 조립하며 만난 func함수의 타입을 보고 리터럴 "Hello World"Text 타입으로 추론합니다. 확장이 꺼져 있으면 에러가 납니다.

Couldn't match expected typeText’ with actual type ‘[Char]’
Github 계정이 없는 분은 메일로 보내주세요. lionhairdino at gmail.com