`where` 子句在 Haskell 中在哪里派上用场
Posted
技术标签:
【中文标题】`where` 子句在 Haskell 中在哪里派上用场【英文标题】:where does the `where` clause come in handy in Haskell 【发布时间】:2011-08-27 07:02:21 【问题描述】:我发现我很少遇到需要使用where
子句的情况。但是,我确实发现过去我偶尔使用过它。何时使用where
子句(即它在什么情况下使用)?什么情况下应该使用?
【问题讨论】:
在适当的地方使用where
。
您可能会在这个相关问题中找到一些有用的信息:where vs. let
感谢@Thies Heidecke 甚至没有出现!
【参考方案1】:
Haskell Wiki 上也有这个问题的两个很好的答案:
http://haskell.org/haskellwiki/Declaration_vs._expression_style http://haskell.org/haskellwiki/Let_vs._Where
两者都用于创建本地定义,这些定义可能会使用传递到其封闭函数范围内的值,并且在封闭函数的上下文之外肯定不可用。它们促进代码重用并最大限度地减少重复。给定fix
和 lambda,两者都可以完全脱糖。通常,我尽可能使用 where 子句,并且只倾向于在 lambda 或 case 块内或在 do
表示法中使用 let 子句来定义前几行中通过 <-
提取的值。总的来说,我认为声明式风格现在比惯用的现代 Haskell 代码中的表达风格更普遍。
【讨论】:
【参考方案2】:我发现它很重要的一个具体示例 - 一个返回递归定义数组的函数。
lucas :: (Integral a) => a -> Array a
lucas n = a where
a = array (0,n) ((0,2):(1,1):[(i,a!!(i-1) + a!!(i-2)) | i<-[1..n])])
对于卢卡斯数字 1 到 n(斐波那契太明显了 =P)
重要的一点是,如果没有 where 子句,数组将没有函数体内的名称,并且您无法递归定义。
【讨论】:
【参考方案3】:这主要是风格问题。即使它们不完全等效,您也不会经常使用其中一个。相反,这取决于您,您认为更好看。
【讨论】:
【参考方案4】:我的经验法则 - 如果您在函数的顶层定义某些内容,请使用“where”。如果您要定义具有多个子句的辅助函数,请务必使用“where”。其他地方,随便挑一个!
【讨论】:
你的意思是在你说“where”的地方使用“let”吗? 不,我经常使用“where”:)【参考方案5】:根据我的经验,where
比 let
更具可读性,因为它的读法通常与英语非常相似。
例如:
myFun x = aCoefficient * (10 ** anExponent)
where aCoefficient = 100 - x
anExponent = x - 2
在英语中,我将其描述为“myFun of x 是一个系数乘以(10 到一个指数),其中系数是 100 减去 x,指数是 x 减去 2”
【讨论】:
【参考方案6】:使用where
的两个文体优势:
它将您定义的事物的值放在其名称(和类型)附近。
func x = part1 . part2 (something x)
where part1 = ...
part2 = ...
而不是
func x = let part1 =
part2 =
in part1 . part2 (something x)
它鼓励编写可以阅读“报纸风格”的代码,其中重要的东西在前,所有的细节在后。这样一来,您就可以在觉得不需要了解其余细节时停止阅读。
func x = highlevel1 . highlevel2 (x + 42)
where highlevel1 = medium (...)
highlevel2 = medium (...)
medium = ...
当绑定本身比表达式更有趣并且它们很短时,我主要使用let
。例如,当绑定只是为了进行模式匹配时:
func x = let (MyData y _ _) = something in y
在我看来这看起来比
func x = y
where (MyData y _ _) = something
【讨论】:
以上是关于`where` 子句在 Haskell 中在哪里派上用场的主要内容,如果未能解决你的问题,请参考以下文章
如何在 where 子句上基于 SqlCommand 或 SqlDataAdapter 填充 datagridview? SqlDataAdapter 不适用于哪里?
索引问题:Select * with WHERE 子句。在哪里以及如何创建索引