2014-11-06 16 views
10

OverloadedStrings uzantısı gerçekten çok yararlıdır, ancak bazı olumsuzlukları vardır. OverloadedStrings etkinleştirildiğinde ben değişmez bir değer geçmek istiyorsan açıkça bir tür imza eklemek zorunda Bu durumdaAşırı Yüklenen Dizeleri Kullanmak

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

: aşağıdaki işlevi tanımı düşünün

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

Bunun nedeni gereklilik oldukça barizdir, sanırım, OverloadedStrings, katı tip imzalara sahip olan işlevlere değişmez değerlerin geçişini kolaylaştırmak için tasarlandı ve geliştiricinin Text değerinin gerekli olduğu her yerde geliştiriciyi pack s yazmasına izin vermez.

Soru, "Text veya String" tür imzaları olmayan tüm dize değişmezlerini varsayılan olarak söylemek için herhangi bir yol var mı? Yoksa kodumu genel işlevlerine (ToJSString tipi kısıtlama ile) ve argümanları için katı tip imzaları olan keyfi olanlara ayırmalı mıyım?

cevap

22

Sen de (https://www.fpcomplete.com/user/snoyberg/random-code-snippets/overloadedstrings-defaults) ExtendedDefaultRules etkinleştirebilirsiniz: Ayrıca modülün üstüne default (Text) eklemek isteyebilirsiniz

{-# 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" 

DÜZENLEME varsayılan olarak Text yerine String kullanmasını sağlamak için.

+1

Beni şaşırtmaktan asla vazgeçmiyorsun! Çok teşekkürler. –