Pro*_*sov 5 haskell instanceof
我是Haskell的新手,所以我的问题可能很愚蠢.
我想要一个功能
show2 :: (Show a) => a -> String
Run Code Online (Sandbox Code Playgroud)
这将返回show a任何a,但a如果一个本身String.我该如何实现它?
如果这个功能已经在某个地方实现了,那就太好了,但是我仍然希望看到一个实现的例子.
您可以使用cast从Data.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)
您可以使用这段肮脏而危险的代码来做到这一点:
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)
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
-- ...
Run Code Online (Sandbox Code Playgroud)