Haskell 我应该总是更喜欢一般类型而不是特定类型吗?

Haskell 我应该总是更喜欢一般类型而不是特定类型吗?,haskell,polymorphism,ghc,Haskell,Polymorphism,Ghc,使用ghc--make编译,这两个程序生成完全相同的二进制文件: -- id1a.hs main = print (id' 'a') id' :: a -> a id' x = x -- id1b.hs main = print (id' 'a') id' :: Char -> Char id' x = x 这仅仅是因为我的例子是多么琐碎/做作,还是这样 随着程序变得越来越复杂,这是否成立 还有,有没有什么好的理由避免让我的类型尽可能的通用 可能的我通常会把细节放在我不需要的

使用
ghc--make
编译,这两个程序生成完全相同的二进制文件:

-- id1a.hs
main = print (id' 'a')

id' :: a -> a
id' x = x

-- id1b.hs
main = print (id' 'a')

id' :: Char -> Char
id' x = x
这仅仅是因为我的例子是多么琐碎/做作,还是这样 随着程序变得越来越复杂,这是否成立

还有,有没有什么好的理由避免让我的类型尽可能的通用 可能的我通常会把细节放在我不需要的地方,但是 我不太熟悉这对编译语言的影响, 尤其是Haskell/GHC

旁注:

我似乎还记得最近的一个问题,答案是使一个类型更复杂 为了改善某些性能问题,虽然我找不到它 现在,我可能已经想到了

编辑:


我从可用性/可组合性的角度理解,越通用越好,我对这对编译代码的影响更感兴趣。我是否可能过于热衷于抽象代码?或者这在Haskell中通常不是一个问题吗?

我会尽可能地把所有的事情都概括起来。如果您遇到性能问题,您可以开始考虑打乱具体的实现,但我认为这不是一个经常出现的问题,如果这真的出现了问题,那么您的性能需求可能会非常大,可以考虑再次进入命令式领域;)

在我看来,常规类型通常会使函数更可用

这可能是一个糟糕的例子,但是如果您正在编写一个函数,比如elem(获取一个列表和一个元素,如果列表包含该元素,则返回true,否则返回false),那么使用特定类型将限制函数的可用性。例如,如果将类型指定为Int,则不能使用该函数检查字符串是否包含特定字符

我对性能不是很确定,但我没有遇到任何问题,我几乎一直使用常规类型

这仅仅是因为我的例子是多么的琐碎/做作吗

对。也就是说,尝试将
id'
main
的定义拆分为不同的模块,您应该会看到不同之处

然而,Carsten是对的:使用具体类型可能有性能相关的原因,但通常应该从一般类型开始,只有在实际存在问题时才使用具体实现

有什么好的理由不让我的类型尽可能的通用吗


不,只要你有足够的时间来处理那些极为罕见的情况,而这些情况实际上可能很重要。

“也许你的绩效需求会很高,以至于你可以考虑再次搬家。”-我相信你低估了哈斯克尔支持高效命令代码的能力。当然,在那些情况下,C++编写或任何可能更容易生成高性能代码的方法(这些语言仍然有使用的原因))我认为更普遍的是更好的可用性的观点。我最喜欢的反例是
Control.Monad.forever::Monad m=>ma->mb
。该类型签名非常通用,如果在作用域中有正确的实例,您可以编写
main=forever putStrLn“hello!”
,它将在没有任何警告的情况下进行类型检查和编译,然后在运行时进行无限循环。都是因为你忘了一个
$
。记住,通用性意味着更多的程序类型检查,在某些情况下,这意味着更多错误的程序类型检查——通常,类型错误是一件好事。通常情况下,概括所有事情,尽管如此。。。我想永远不要用“总是”或“从不”这样的词,除非在这句话中,也就是说: