Haskell模拟实例?

Pro*_*sov 5 haskell instanceof

我是Haskell的新手,所以我的问题可能很愚蠢.

我想要一个功能

show2 :: (Show a) => a -> String
Run Code Online (Sandbox Code Playgroud)

这将返回show a任何a,但a如果一个本身String.我该如何实现它?

如果这个功能已经在某个地方实现了,那就太好了,但是我仍然希望看到一个实现的例子.

Lee*_*Lee 5

您可以使用castData.Typeable

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


n. *_* m. 5

您可以使用这段肮脏而危险的代码来做到这一点:

class Showable a where
  show2 :: a -> String

instance Showable String where
  show2 = id

instance (Show a) => Showable a where
  show2 = show
Run Code Online (Sandbox Code Playgroud)

您需要 -XOverlappingInstances -XFlexibleInstances -XUndecidableInstances编译并使用它。

*Main> show2 "abc"
"abc"
*Main> show2 3
"3"
Run Code Online (Sandbox Code Playgroud)

  • {-#LANGUAGE ...#-}`编译指示通常比`-X`标志好。 (2认同)

Lui*_*las 5

Haskell的设计方式与instanceof支票的概念非常相反。Haskell的设计没有包含这种运行时类型检查,因为Haskell非常专注于强大的编译时保证:一个函数在运行时不应该能够比在编译时知道它们更精确地学习其参数类型。

这并不意味着该功能在Haskell中不存在-Lee的答案演示了如何实现-但是在Haskell中,这是提供的可选功能,不是该语言的核心部分(不同于Java,它是始终存在的核心功能-您不能选择退出!)。

注意,即使在面向对象的编程中,instanceof运算符也是有争议的。许多面向对象的程序员强烈建议不要使用它。几个例子(数百个例子):

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

该建议可以直接翻译为Haskell:

  1. 定义自己的类型类以表示所需的行为
  2. 为您感兴趣的每种类型实现此类型类,并为每种类型提供正确的行为。

因此,您可以执行以下操作:

class ToString a where
    toString :: a -> String

instance ToString String where
    toString str = str

instance ToString Integer where
    toString i = show i

-- ...
Run Code Online (Sandbox Code Playgroud)