gpt4 book ai didi

haskell - 对 Haskell 多态类型感到困惑

转载 作者:行者123 更新时间:2023-12-02 02:50:08 24 4
gpt4 key购买 nike

我定义了一个函数:

gen :: a -> b

所以只是试图提供一个简单的实现:
gen 2 = "test"

但抛出错误:
gen.hs:51:9:
Couldn't match expected type ‘b’ with actual type ‘[Char]’
‘b’ is a rigid type variable bound by
the type signature for gen :: a -> b at gen.hs:50:8
Relevant bindings include gen :: a -> b (bound at gen.hs:51:1)
In the expression: "test"
In an equation for ‘gen’: gen 2 = "test"
Failed, modules loaded: none.

所以我的功能不正确。为什么是 a未输入为 Int 和 b没有输入为 String ?

最佳答案

这是一个很常见的误解。

要理解的关键是,如果您的类型签名中有一个变量,那么调用者可以决定它是什么类型,而不是您!

所以你不能说“这个函数返回类型 x”然后只返回一个 String ;您的函数实际上必须能够返回调用者可能要求的任何可能类型。如果我要求您的函数返回 Int ,它必须返回一个 Int .如果我要求它返回 Bool ,它必须返回一个 Bool .

您的函数声称能够返回任何可能的类型,但实际上它只返回 String .所以它不会做类型签名声称它做的事情。因此,编译时错误。

很多人显然误解了这一点。在(比如说)Java 中,你可以说“这个函数返回 Object”,然后你的函数可以返回它想要的任何东西。所以函数决定它返回什么类型。在 Haskell 中,调用者可以决定返回什么类型,而不是函数。

编辑:注意你写的类型,a -> b , 是不可能的。没有函数可以有这种类型。函数无法构造 b 类型的值凭空。唯一可行的方法是如果某些输入也涉及类型 b ,或者如果 b属于某种允许值构造的类型类。

例如:

head :: [x] -> x

这里的返回类型是 x (“任何可能的类型”),但输入类型也提到了 x ,所以这个功能是可能的;您只需要返回原始列表中的值之一。

同样, gen :: a -> a是一个完全有效的函数。但它唯一能做的就是原封不动地返回它的输入(即 id 函数所做的)。

类型签名的这个属性告诉你函数的作用是 Haskell 的一个非常有用和强大的属性。

关于haskell - 对 Haskell 多态类型感到困惑,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30217354/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com