仅将字符串文字限制为文本 [英] Restricting string literals to Text only

查看:129
本文介绍了仅将字符串文字限制为文本的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我知道, OverloadedStrings 语言编译指令在所有字符串文字周围隐含了一个隐含的 fromString 。我想要做的不是重载字符串,而只是改变它们的含义,使它们始终变成 Text ,因此,使用字符串作为字符列表应该导致类型错误。



似乎不可能导入 IsString 类,而不导入该类的 String 实例。 ghc是否提供了一些方法让我将字符串文字限制为 Text only?

解决方案

这有点矫枉过正,但一种解决方案是将 OverloadedStrings RebindableSyntax RebindableSyntax 扩展会导致Haskell语法使用的所有隐式函数调用引用范围内的任何函数;例如,整数文字使用fromIntegral 中的任何,而不一定是 Prelude.fromIntegral 。作为副作用, Prelude 不再被隐式导入,因此您必须手动执行此操作。只要你 导入它,隐式地使用错误函数的语法应该没有任何问题(我想 - 我实际上并没有使用这种技术)。当与 OverloadedStrings 结合使用时,这会将foo转换为 fromStringfoo 适用于任何 fromString 的范围内,不一定 Data.String.fromStringfoo。因此,使 fromString pack 同义将会做你想做的事。一个完整的例子:

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

将合格的Data.Text导入为T
将合格的Data.Text.IO导入为T

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

main :: IO()
main = T.putStrLnHello,world!

这可以正常工作,并将 main 更改为 main = putStrLnHello,world!会产生所需的错误:

  TestStrings.hs:11:17:
无法与实际类型为T.Text的预期类型String匹配
预期类型:[Char] - >字符串
实际类型:字符串 - > T.Text
在`putStrLn'的第一个参数中,即`Hello,world!'
在表达式中:putStrLnHello,world!

注释 fromString 的定义会导致a不同的错误:

  TestStrings.hs:11:19:
不在范围内:`fromString'
也许你的意思是`showString'(从Prelude导入)

如果你想让它同时适用于strict和懒惰的文本,你可以定义你自己的 IsString 类型,并使它们成为两个实例;这个类不一定要被称为 IsString ,只要它有一个 fromString 方法。



另外,一句警告: RebindableSyntax 的GHC手册部分没有提及 fromString 函数,而 OverloadedStrings 一节没有提及 RebindableSyntax 。没有理由不应该这样做,但我认为这意味着此解决方案在技术上依赖于无证行为。


I'm aware that the OverloadedStrings language pragma wraps an implicit fromString around all string literals. What I'd like to do is not actually overload strings, but merely change their meaning so that they are always turned into Text, and therefore, using a string literal as a list of characters should result in a type error.

It appears to be impossible to import the IsString class without also importing the String instance for that class. Does ghc provide some way for me to restrict string literals to Text only?

解决方案

It's a little bit of overkill, but one solution is to combine OverloadedStrings and RebindableSyntax. The RebindableSyntax extension causes all the implicit function calls that Haskell syntax uses to refer to whatever functions are in scope; for instance, integer literals use any fromIntegral, not necessarily Prelude.fromIntegral. As a side effect, Prelude is no longer implicitly imported, so you have to do that manually. As long as you do import it, there shouldn't be any issues with syntax using the wrong function implicitly (I think—I haven't actually used this technique). When combined with OverloadedStrings, this causes "foo" to be transformed into fromString "foo" for whatever fromString's in scope, not necessarily Data.String.fromString "foo". So making fromString synonymous with pack will do what you want. A complete example:

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

This works fine, and changing main to main = putStrLn "Hello, world!" produces the desired error:

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!"

Commenting out the definition of fromString causes a different error:

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

If you want it to work with both strict and lazy text, you could define your own IsString type class, and make both of them instances; the class doesn't have to be called IsString, just so long as it has a fromString method.

Also, a word of warning: the section of the GHC manual on RebindableSyntax doesn't mention the fromString function, and the section on OverloadedStrings doesn't mention RebindableSyntax. There's no reason this shouldn't work, but I think that means that this solution technically relies on undocumented behavior.

这篇关于仅将字符串文字限制为文本的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆