haskell – 将字符串文字限制为仅文本

我知道OverloadedStrings语言pragma包装一个隐含的fromString周围的所有字符串文字。我想做的不是实际重载字符串,而只是改变它们的意思,使它们总是变成Text,因此,使用字符串字面量作为字符列表应该导致类型错误。

似乎是不可能导入IsString类,而不导入该类的String实例。 ghc为我提供了一些方法来限制字符串文字只有文本?

最佳答案
这是一个有点过分,但一个解决方案是组合OverloadedStringsRebindableSyntax.RebindableSyntax扩展导致所有隐式函数调用Haskell语法使用来引用范围内的任何函数;例如,整数文字使用任何fromIntegral,不一定是Prelude.fromIntegral。作为副作用,Prelude不再隐式导入,因此您必须手动进行。只要你导入它,不应该有任何问题的语法使用错误的函数隐式(我想 – 我没有实际使用这种技术)。当与OverloadedStrings结合使用时,这将导致“foo”被转换为fromString“foo”用于范围内的任何fromString,不一定是Data.String.fromString“foo”。所以使fromString与pack的同义词将做你想要的。一个完整的例子:

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

这工作正常,并将main更改为main = putStrLn“Hello,world!”产生所需的错误:

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

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

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

如果你想要使用strict和lazy文本,你可以定义你自己的IsString类型类,并使它们两个实例;该类不必被称为IsString,只要它有一个fromString方法。

另外,一个警告:RebindableSyntax的GHC手册部分没有提到fromString函数,OverloadedStrings部分没有提到RebindableSyntax。没有理由这不应该工作,但我认为这意味着这个解决方案在技术上依赖于未记录的行为。

转载注明原文:haskell – 将字符串文字限制为仅文本 - 代码日志