Haskell - 类型和 if 语句
有没有一个好的方法可以使用类型信息来选择做不同的事情?
例如,这不是有效的 Haskell,但我不明白为什么它不能:
tostring :: (Show b) => b -> String
tostring x = f x where f = if b == String then tail . init . show else show
重要的部分不是获取正确的字符串,而是使用 b
的类型作为一种方式在功能/功能之间切换。
Is there a good way to use type information to choose to do different things?
For example, this isn't valid Haskell, but I don't see why it couldn't be:
tostring :: (Show b) => b -> String
tostring x = f x where f = if b == String then tail . init . show else show
The important part is not getting the correct string out, but using the type of b
as a way to switch between functionality/functions.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
@chi 的答案已经演示了如何使用
Typeable
进行运行时类型检查,但我想指出,对我来说,这看起来正是类型类的用途。对于您的示例,唯一的问题是您不喜欢String
的Show
实现:在这种情况下,只需创建您自己的类型类!编辑:正如 leftaroundabout 所指出的,重叠实例很复杂,可能会导致一些意外的行为。查看 文档底部的示例。
@chi's answer already demonstrates how to use
Typeable
to do run-time type checking, but I'd like to point out that to me, this looks like exactly the thing typeclasses are meant for. For your example, the only problem is that you don't like theShow
implementation forString
: In that case, just create your own typeclass!EDIT: As pointed out by leftaroundabout, overlapping instances are complicated and can lead to some unexpected behavior. Look at the example at the bottom of the documentation.
我将按原样回答这个问题。 Haskell 在编译时删除所有类型信息,主要是出于效率原因。默认情况下,当调用多态函数时,例如
f :: a->a
,没有可用的类型信息,并且f
无法知道>a
实际上是 - 在这种情况下,f
只能是恒等函数,无法终止或引发错误。对于需要类型信息的极少数情况,可以使用
Typeable
。具有类型f :: Typeable a => 的多态函数...
传递了类型a
的运行时描述,允许对其进行测试。本质上,Typeable a
约束强制 Haskell 保留运行时信息直到运行时。请注意,这样的类型信息在调用站点必须是已知的——要么是因为f
是用完全已知的类型调用的,要么是因为f
是用部分已知的类型调用的(说f x
与x :: Maybe b
),但范围内有合适的Typeable
约束(Typeable b
,在前面的例子)。不管怎样,这里有一个例子:
注意我们如何能够在“then”分支中返回
x
,因为在那里它已知是一个String
。I will answer the question as it is. Haskell erases all type information during compile time, mostly for efficiency reasons. By default, when a polymorphic function is called, e.g.
f :: a->a
, no type information is available, andf
has no way to know whata
actually is -- in this case,f
can only be the identity function, fail to terminate, or raise an error.For the rare cases where type information is needed, there is
Typeable
. A polymorphic function having typef :: Typeable a => ...
is passed a run-time description of the typea
, allowing it to test it. Essentially, theTypeable a
constraint forces Haskell to keep the runtime information until run time. Note that such type information must be known at the call site -- either becausef
is called with a completely known type, or becausef
is called with a partially known type (sayf x
withx :: Maybe b
) but there are suitableTypeable
constraints in scope (Typeable b
, in the previous example).Anyway, here's an example:
Note how we were able to return
x
in the "then" branch, since there it is known to be aString
.