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