43 votes

Restreindre les littéraux de chaîne au texte uniquement

Je suis conscient que l' OverloadedStrings langue pragma encapsule une implicite fromString autour de tous les littéraux de chaîne. Ce que je voudrais faire est de ne pas en fait de la surcharge des chaînes, mais simplement de modifier leur sens de sorte qu'ils sont toujours transformées en Text, et par conséquent, à l'aide d'un littéral de chaîne comme une liste de caractères devrait entraîner une erreur de type.

Il semble impossible d'importer l' IsString classe sans l'importation de l' String instance de cette classe. Ne ghc prévoir un moyen pour moi de limiter les littéraux de chaîne d' Text seulement?

51voto

Antal S-Z Points 17977

C'est un peu exagéré, mais la seule solution est de combiner OverloadedStrings et RebindableSyntax. L' RebindableSyntax extension provoque tous les implicites appels de la fonction de Haskell syntaxe utilise pour se référer à ce que les fonctions sont dans le champ d'application; par exemple, les littéraux entiers utiliser tout fromIntegral, pas nécessairement Prelude.fromIntegral. Comme un effet secondaire, Prelude n'est plus implicitement importés, de sorte que vous avez à faire que manuellement. Tant que vous ne l'importer, il ne devrait pas y avoir de problèmes avec la syntaxe à l'aide de la fonction incorrecte implicitement (je pense-je n'ai pas réellement utilisé cette technique). Lorsqu'il est combiné avec OverloadedStrings, ce qui provoque "foo" pour être transformé en fromString "foo" pour tout - fromStrings'dans le champ d'application, pas nécessairement Data.String.fromString "foo". Afin de faire la fromString synonyme d' pack à faire ce que vous voulez. Un exemple complet:

{-# LANGUAGE OverloadedStrings, RebindableSyntax #-}
import Prelude

import qualified Data.Text    as T
import qualified Data.Text.IO as T

fromString :: String -> T.Text
fromString = T.pack

main :: IO ()
main = T.putStrLn "Hello, world!"

Cela fonctionne bien, et l'évolution main de main = putStrLn "Hello, world!" produit souhaité en erreur:

TestStrings.hs:11:17:
    Couldn't match expected type `String' with actual type `T.Text'
    Expected type: [Char] -> String
      Actual type: String -> T.Text
    In the first argument of `putStrLn', namely `"Hello, world!"'
    In the expression: putStrLn "Hello, world!"

Commentant la définition de l' fromString provoque une erreur différents:

TestStrings.hs:11:19:
    Not in scope: `fromString'
    Perhaps you meant `showString' (imported from Prelude)

Si vous voulez qu'il fonctionne à la fois stricte et paresseuse de texte, vous pouvez définir votre propre IsString type de classe, et de faire les deux cas, la classe n'a pas à être appelés IsString, juste aussi longtemps que il a un fromString méthode.

Aussi, un mot d'avertissement: la section de la GHC manuel sur RebindableSyntax ne parle pas de l' fromString de la fonction, et la section sur l' OverloadedStrings ne pas mentionner RebindableSyntax. Il n'y a pas de raison que cela ne devrait pas travailler, mais je pense que cela signifie que cette solution, techniquement, s'appuie sur les sans-papiers comportement.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X