当前位置:  开发笔记 > 编程语言 > 正文

是否有用于启用重载字符文字的GHC扩展?

如何解决《是否有用于启用重载字符文字的GHC扩展?》经验,为你挑选了2个好方法。

我知道有一个GHC扩展名,OverloadedStrings它允许字符串文字(由分隔")变成多态的,类似于数字文字的内置行为。

我的问题是:是否存在GHC扩展,该扩展允许单字符文字(以分隔')以类似的方式变为多态?



1> Alec..:

不是从GHC 8.8开始,但是您可以使用QuasiQuotes扩展名将其扩展。这是一个仅接受一个ascii字符并将其转换为其字节表示形式的准引用的示例。

import Language.Haskell.TH
import Language.Haskell.TH.Quote
import Language.Haskell.TH.Syntax

import Data.Word (Word8)
import Data.Char (isAscii)

asciiByte :: QuasiQuoter
asciiByte = QuasiQuoter
  { quoteExp = \str -> case str of
                         [c] | isAscii c -> lift (fromIntegral (fromEnum c) :: Word8)
                         _ -> fail ("asciiByte: expects a single ascii character, got " ++ str) 
  , quotePat = \_ -> fail "asciiByte: only available for expressions"
  , quoteType = \_ -> fail "asciiByte: only available for expressions"
  , quoteDec = \_ -> fail "asciiByte: only available for expressions"
  }

然后,您可以将其用作:

ghci> [asciiByte|a|]
97
ghci> [asciiByte|é|]

:75:12: error:
    • asciiByte: expects a single ascii character, got é
    • In the quasi-quotation: [asciiByte|é|]
ghci> [asciiByte|abc|]

:76:12: error:
    • asciiByte: expects a single ascii character, got abc
    • In the quasi-quotation: [asciiByte|abc|]



2> Joachim Brei..:

没有。

让我通过对GHC源代码的一些探索来回答这个问题:

这是在重命名器中OverloadedString生效的代码:

rnExpr (HsLit x lit@(HsString src s))
  = do { opt_OverloadedStrings <- xoptM LangExt.OverloadedStrings
       ; if opt_OverloadedStrings then
            rnExpr (HsOverLit x (mkHsIsString src s))
         else do {
            ; rnLit lit
            ; return (HsLit x (convertLit lit), emptyFVs) } }

rnExpr (HsLit x lit)
  = do { rnLit lit
       ; return (HsLit x(convertLit lit), emptyFVs) }

rnExpr (HsOverLit x lit)
  = do { ((lit', mb_neg), fvs) <- rnOverLit lit -- See Note [Negative zero]
       ; case mb_neg of
              Nothing -> return (HsOverLit x lit', fvs)
              Just neg -> return (HsApp x (noLoc neg) (noLoc (HsOverLit x lit'))
                                 , fvs ) }

(https://github.com/ghc/ghc/blob/c2991f16cb6f5b4e7cff46a394dda4247d973f44/compiler/rename/RnExpr.hs#L152)

您会看到字符串有特殊处理,但其他形式的文字则没有。最后一个子句用于根据原始Haskell标准重载的文字,正如我们在解析器的以下几行中所看到的:

        | literal                       { ECP $ mkHsLitPV $! $1 }
-- This will enable overloaded strings permanently.  Normally the renamer turns HsString
-- into HsOverLit when -foverloaded-strings is on.
--      | STRING    { sL (getLoc $1) (HsOverLit $! mkHsIsString (getSTRINGs $1)
--                                       (getSTRING $1) noExt) }
        | INTEGER   { ECP $ mkHsOverLitPV (sL1 $1 $ mkHsIntegral   (getINTEGER  $1)) }
        | RATIONAL  { ECP $ mkHsOverLitPV (sL1 $1 $ mkHsFractional (getRATIONAL $1)) }

(https://github.com/ghc/ghc/blob/c2991f16cb6f5b4e7cff46a394dda4247d973f44/compiler/parser/Parser.y#L2793)

literal :: { Located (HsLit GhcPs) }
        : CHAR              { sL1 $1 $ HsChar       (getCHARs $1) $ getCHAR $1 }
        | STRING            { sL1 $1 $ HsString     (getSTRINGs $1)
                                                    $ getSTRING $1 }
        | PRIMINTEGER       { sL1 $1 $ HsIntPrim    (getPRIMINTEGERs $1)
                                                    $ getPRIMINTEGER $1 }
        | PRIMWORD          { sL1 $1 $ HsWordPrim   (getPRIMWORDs $1)
                                                    $ getPRIMWORD $1 }
        | PRIMCHAR          { sL1 $1 $ HsCharPrim   (getPRIMCHARs $1)
                                                    $ getPRIMCHAR $1 }
        | PRIMSTRING        { sL1 $1 $ HsStringPrim (getPRIMSTRINGs $1)
                                                    $ getPRIMSTRING $1 }
        | PRIMFLOAT         { sL1 $1 $ HsFloatPrim  noExt $ getPRIMFLOAT $1 }
        | PRIMDOUBLE        { sL1 $1 $ HsDoublePrim noExt $ getPRIMDOUBLE $1 }

(https://github.com/ghc/ghc/blob/c2991f16cb6f5b4e7cff46a394dda4247d973f44/compiler/parser/Parser.y#L3708)

推荐阅读
k78283381
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有