Haskell模拟实例?

Haskell模拟实例?,haskell,instanceof,Haskell,Instanceof,我是哈斯克尔的新手,所以我的问题可能很愚蠢 我想要一个函数 show2 :: (Show a) => a -> String 它将返回为任何a显示一个,但如果a本身是字符串,则返回a。 我如何实现它 另外,如果这个函数已经在某个地方实现了,那就太好了,但是我仍然想看一个实现的例子。您可以使用数据中的强制转换。可键入的 show2 :: (Typeable a, Show a) => a -> String show2 s = maybe (show s) id ms

我是哈斯克尔的新手,所以我的问题可能很愚蠢

我想要一个函数

show2 :: (Show a) => a -> String
它将返回
为任何
a
显示一个
,但如果a本身是
字符串
,则返回
a
。 我如何实现它


另外,如果这个函数已经在某个地方实现了,那就太好了,但是我仍然想看一个实现的例子。

您可以使用
数据中的
强制转换
。可键入的

show2 :: (Typeable a, Show a) => a -> String
show2 s = maybe (show s) id ms
  where ms = cast s :: Maybe String

您可以使用这段肮脏而危险的代码:

class Showable a where
  show2 :: a -> String

instance Showable String where
  show2 = id

instance (Show a) => Showable a where
  show2 = show
您需要
-XOverlappingInstances-XFlexibleInstances-XUndecidableInstances
来编译和使用它

*Main> show2 "abc"
"abc"
*Main> show2 3
"3"

Haskell的设计方式与
instanceof
检查的概念截然不同。Haskell的设计没有包含这种运行时类型检查,因为Haskell非常关注强编译时间保证:函数在运行时不能比在编译时更准确地了解其参数的类型

这并不意味着Haskell Lee的回答演示了如何实现这一点,但在Haskell中,这是一个库提供的选择加入功能,而不是语言的核心部分(不像Java这样的语言,它是一个始终存在的核心功能,你不能选择退出它!)

注意,即使在面向对象编程中,
instanceof
操作符也是有争议的。许多面向对象的程序员强烈反对使用它。几个示例(数百个示例中):

所有这些中的建议都是一样的:不要使用测试引用类型并基于它切换到不同的行为,而是使用多态性:定义一个接口或类,该接口或类具有用于所需操作的方法,让您使用
instanceof
测试的对象实现其自己的方法版本,以执行正确的操作

此建议可直接翻译为Haskell:

  • 定义自己的类型类来表示所需的行为
  • 为您感兴趣的每个类型实现这个类型类,每个类型都有正确的行为
  • 所以,你可以这样做:

    class ToString a where
        toString :: a -> String
    
    instance ToString String where
        toString str = str
    
    instance ToString Integer where
        toString i = show i
    
    -- ...
    

    不管它值多少钱,这通常是个坏主意。顺便说一句,你可能已经知道了这一点,但因为你是新来的:
    =>
    前面的部分被称为上下文(在你的例子中,它是
    Show a
    )。既然只有一个,你就不必用括号了。@LouisWasserman,你能解释一下,为什么吗?@事后看来,在Haskell中做任何形式的反思逻辑都是不可取的;“特定类型的异常”之类的东西是不受欢迎的。@事后来看,之所以不受欢迎,是因为参数性被发现是代码极有价值的属性;如果函数在某些类型变量中是多态的,那么它将以相同的方式统一处理所有类型。这会使代码更加可重用、可组合和易于推理。
    {-#LANGUAGE…#-}
    pragmas通常比
    -X
    标志更好。太棒了!我可以做一些类似于
    实例Show a=>到字符串a
    的事情吗?