关于Haskell';s参数概念

关于Haskell';s参数概念,haskell,Haskell,这是《Haskell从第一原理编程》一书中的一个问题 我正在读上面提到的书,关于第5章,练习2:参数学 从书上抄下来的 我们可以更轻松地欣赏参数 通过查看a->a->a。这个假设 函数a->a->a有两个且只有两个实现。 我不明白“只有两个实现”部分?有人能向我解释为什么只有两种实现吗 我认为“实现”一词乍一看可能有点让人困惑 假设我们只有函数类型f::a->a->a,没有其他信息;我们不允许在f内偷看。函数必须返回一个a,并且您只有两个可能的a作为输入。因此,函数必须返回第一个a或第二个a;只

这是《Haskell从第一原理编程》一书中的一个问题

我正在读上面提到的书,关于第5章,练习2:参数学

从书上抄下来的

我们可以更轻松地欣赏参数 通过查看a->a->a。这个假设 函数a->a->a有两个且只有两个实现。

我不明白“只有两个实现”部分?有人能向我解释为什么只有两种实现吗

我认为“实现”一词乍一看可能有点让人困惑

假设我们只有函数类型
f::a->a->a
,没有其他信息;我们不允许在
f
内偷看。函数必须返回一个
a
,并且您只有两个可能的
a
作为输入。因此,函数必须返回第一个
a
或第二个
a
;只有两种可能的功能

你不能有
fxy=x+y
,因为你不知道如何
+
两个
a
,因为
f::a->a->a
。如果你有,比如说
h::Int->Int->Int
,那么
hxy=x+y
将是一个有效的函数,但是你没有得到
f
的信息

类似地,如果您拥有
f::a->a->a
,并且您声称
fxy=x+y
有效,该怎么办。然后我可以通过将两个
水果
s传递给
f
f苹果橙=???
,来打破你的要求。嗯,
Apple+Orange
模棱两可,代码不起作用。因此,保持类型多态性将可能的函数“限制”为两种可能的“实现”:
fxy=x
fxy=y

这有助于我理解。我推荐整个视频,但链接是相关部分。(31:28)

它展示了类型级推理和参数化的能力。此类推理的所有信息都在类型中


另一个例子是,假设您只有一个函数类型
g::b->b
。函数必须返回a
b
,唯一的参数是a
b
,因此它必须返回该
b
。因此,只有一个类型为
b->b

的函数我不确定是否可以正式解释,但只要想办法实现一个函数,给定同一类型的两个元素,就可以为每种可能的类型生成一个该类型的函数。这两种可能的实现是相当明显的,而且(非正式地说)没有“你能做的其他事情”,因为你不能对函数所取的值做任何假设,因为你对它们的类型一无所知。
\nf x y=x f x y=y f x y=x+y\n
,所以我定义了3个函数最后一个函数没有type
a->a->a
,但是
Num a=>a->a->a
。假设我给你两个框,我告诉你这些框中的东西是同一类型的东西,但我不告诉你它们是什么。现在我请你给我一些同样类型的东西,果断地(不要用
IO
掷硬币)和“诚实地”(不要打开盒子看里面有什么,不要对我撒谎说你给了我什么,不要带着盒子跑掉,再也不回来)。既然你对盒子里的东西一无所知,你不能只做那种类型的东西你必须把我给你的一个盒子还给我,你只有两个可能的选择。@JonPurdy,这个解释很好,谢谢你。第三个返回
undefined
fab=undefined
。甚至还有更多的定义,
fab=fab
fab=faa
,甚至
fab=f(fab)(faa)
,但它们都“返回”
未定义的
@Will,任何签名的任何函数都可以返回
未定义的
。它可以做到这一点,而不必检查它的参数。所以它不算作参数。您的无限递归示例根本不会返回,因此它们也不算数@达沃斯:回答得好@是的,这就是我所说的“它们都‘返回’
undefined
”(错误和循环都被视为底部)。因此,撇开这种“解决方案”不谈,它确实是两种。但我们确实需要打折,参数性是总函数的一个性质;“返回”未定义的部分函数。(术语“总函数”是一个缩略词;从历史上看,函数根据定义将其域中的每个值映射到其共域中的一个值。从这个意义上说,部分函数根本不是函数。)部分函数有参数性,它只是稍微复杂一点,但你仍然可以从类型中导出定律。然而,我认为每个人在实践中都使用总体规律;在实际的Haskell中,在大多数情况下假装一切都是完整的是非常好的,如果事情变得非常微妙,留下底部作为逃生舱口。但总体而言,即所谓的“快而松”,推理效果相当不错。