Haskell:“通用”类型的表达

时间:2012-09-01 21:28:26

标签: haskell types type-inference variable-types

在与this question中显示的类似问题中,是否可能有一个Haskell表达式" generic"输入?像,

myExpression :: a

我是Haskell的新手,但从我所看到的情况来看,这是无法实现的。

3 个答案:

答案 0 :(得分:7)

不,没有任何东西可以满足除底部之外的其他东西,例如

myExpression = myExpression

-- or,

myExpression = undefined

可以可以合理的方式吗?一些非底部表达式,IntegerMaybe (String -> IO ())类型(例如)。


此外,鉴于the question you mention,其中一个答案证明了唯一具有类型签名a -> a的非底层函数是id,我们有一个证据表明不存在类型为a的非底部表达式。如果有,那么

f _ = myExpression

可以有a -> a类型,这既不是id也不是底层,即矛盾。

答案 1 :(得分:1)

您可以将该类型签名读作“适用于所有类型 a ,myExpression类型为 a ”。这意味着myExpression必须是所有类型中存在的某个值。

从数学上讲,没有这样的价值存在,因为 a 可能是“獾”或“非獾的东西”,而这两组必然是截然不同的。

在Haskell类型系统中,myExpression唯一有效的值是 undefined ,也就是底部。

答案 2 :(得分:1)

虽然抽象地只有一个值具有“a”类型的底部,但在运行时有各种可能的解释。

myExpression = myExpression

这永远不会终止。

myExpression = undefined

这将(当使用GHC时)打印“ * 例外:Prelude.undefined”

myExpression = error "Hello!

这将打印“ * Exception:Hello!”

myExpression = unsafePerformIO (launchNukes >> fail "BOOM")

此版本底部的行为取决于您导入的库。

由于您询问“通用”类型,您可能意味着可以有用地包含任何值的事物类型。在这种情况下,请查看Data.Dynamic,它允许您将具有内存中表示形式的任何内容转换为“动态”类型的值。之后,当使用“动态”类型的值时,您可以尝试将其转换为更具体的类型,您可以实际执行某些有用的操作。