2014-11-06 7 views
10

OverloadedStrings 확장자는 매우 유용하지만 몇 가지 단점이 있습니다. OverloadedStrings 기능이 활성화 된 상태가 리터럴 값을 전달하려면 내가 명시 적으로 타입 서명을 추가해야이 경우오버로드 된 문자열 사용

someFunction :: ToJSSTring a => a -> IO() 
someFunction = js_function . toJSSTring 

: 다음 함수 정의를 고려

someFunction ("This is plain string" :: String) 
someFunction ("And this one is Text" :: Data.Text.Text) 

그 이유를 필자는 OverloadedStrings이 엄격한 타입 시그니처가있는 함수에 리터럴 값을 쉽게 전달하도록 설계되어 Text 값이 필요한 모든 곳에서 개발자가 자유롭게 쓸 수 있도록을 작성했다고 가정합니다.

형식 서명이없는 모든 문자열 리터럴을 Text 또는 String으로 기본 설정하는 방법은 무엇입니까? 아니면 내 코드를 일반 함수 (ToJSString 형식 제약 조건 포함)와 그 인수에 엄격한 형식 시그니처가있는 임의의 코드로 분할해야합니까?

답변

22

당신은뿐만 아니라 (https://www.fpcomplete.com/user/snoyberg/random-code-snippets/overloadedstrings-defaults) ExtendedDefaultRules 설정할 수 있습니다 : 당신은 또한 모듈의 상단에 default (Text)을 추가 할 수 있습니다

{-# LANGUAGE FlexibleInstances #-} 
{-# LANGUAGE OverloadedStrings #-} 
{-# LANGUAGE ExtendedDefaultRules #-} 
import Data.Text (Text, pack) 

newtype JSString = JSString Text 
    deriving Show 

class ToJSString a where 
    toJSString :: a -> JSString 
instance ToJSString [Char] where 
    toJSString = toJSString . pack 
instance ToJSString Text where 
    toJSString = JSString 

someFunction :: ToJSString a => a -> IO() 
someFunction = print . toJSString 

main :: IO() 
main = someFunction "Hello World" 

편집이 기본적으로 Text 대신 String을 사용하도록.

+1

당신은 결코 나를 놀라게하지 않습니다! 고마워. –