代码之家  ›  专栏  ›  技术社区  ›  Joey Adams

Haskell:show的变体,它不将字符串和字符括在引号中

  •  3
  • Joey Adams  · 技术社区  · 16 年前

    我想要一种 show label )那就像 显示 ,除了它没有包装 String " " Char s在 ' ' . 示例:

    > label 5
    "5"
    > label "hello"
    "hello"
    > label 'c'
    "c"
    

    {-# LANGUAGE FlexibleInstances #-}
    {-# LANGUAGE UndecidableInstances #-}
    module Label where
    
    class (Show a) => Label a where
        label :: a -> String
    
    instance Label [Char] where
        label str = str
    
    instance Label Char where
        label c = [c]
    
    -- Default case
    instance Show a => Label a where
        label x = show x
    

    instance Label [Char] instance Label Char 标签 功能。

    4 回复  |  直到 15 年前
        1
  •  5
  •   C. A. McCann Ravikant Cherukuri    16 年前

    上面的代码不起作用,因为 实例只能根据“头”来选择 => 例如“Show a”只在事后检查。上下文可以 消除 实例并产生编译器错误,但不会导致编译器 . 由于这种行为,重叠实例是一种潜在的歧义。

    Label 班级。你有什么目的?取决于你想要完成的,可能已经有了一些更特殊的目标。

    不过,您的示例代码非常简单--如果需要,只需添加 OverlappingInstances 扩展应该使它工作,没有进一步的修改。使用 只要有一个明显的“最具体”的实例,GHC就会容忍一些模糊性。在您的代码中,具有具体类型的两个实例尽可能具体,因此不应该有任何问题。

    TypeSynonymInstances

    {-# LANGUAGE FlexibleInstances #-}
    {-# LANGUAGE OverlappingInstances #-}
    {-# LANGUAGE UndecidableInstances #-}
    {-# LANGUAGE TypeSynonymInstances #-}
    module Label where
    
    class (Show a) => Label a where
        label :: a -> String
    
    instance Label String where label x = x
    
    instance Label Char where label x = [x]
    
    instance (Show a) => Label a where label = show
    
        2
  •  1
  •   Michał Marczyk    16 年前

    有一个 OverlappingInstances 语言扩展将使这项工作。

        3
  •  1
  •   katychuang    11 年前

    是否有提供此功能的库函数?

    对。有一个相当新的库提供了一些有用的功能,例如 toS ,可以类似于 show . ( see docs )

    它可以与cabal一起安装在string conv包下,如下所示: cabal install string-conv

    参考文献: Hackage

        4
  •  0
  •   Phyx    16 年前

    不是你想要的,因为它给类型添加了一个额外的约束(Typeable) 但一般来说,你可以这样做:

    Data.Generics>(显示“extQ”(id::String->字符串)`extQ`((:[])::Char->字符串)1

    Data.Generics>(显示“extQ”(id::String->字符串)`extQ`((:[])::Char->“你好”

    “你好”

    “c”

    Data.Generics>(显示“extQ”(id::String->字符串)`extQ`((:[])::Char->字符串))['f','l']

    Data.Generics>:t(显示'extQ'(id::String->字符串)`extQ`((:[])::Char->字符串)

    (显示'extQ'(id::String->字符串)`extQ`((:[])::Char->字符串)

    推荐文章