where does the `where` clause come in handy in Haskell

允我心安 提交于 2019-12-08 20:38:41

问题


I find I quite seldom come across situations where I need to use the where clause. However, I do find that I have used it very occasionally in the past. When is the where clause used (i.e. what situations is it used in)? Under what circumstances should I use it?


回答1:


There are two excellent answers to this question available on the Haskell Wiki as well:

http://haskell.org/haskellwiki/Declaration_vs._expression_style http://haskell.org/haskellwiki/Let_vs._Where

Both are used to create local definitions that perhaps make use of values passed into the scope of their enclosing function, and certainly are not available outside of the context of the enclosing function. They promote code reuse and minimize duplication. Given fix and lambda, both can be desugared away entirely. Generally, I use where clauses whenever possible, and only tend to use let clauses for definitions inside a lambda or case block, or in do notation, when making use of values extracted through <- on previous lines. In general, I think declarative style is now much more prevalant than expression style in idiomatic modern Haskell code.




回答2:


One concrete example where I've found it important - a function returning a recursively defined array.

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])])

For the Lucas numbers 1 thru n (Fibonacci would've just been too obvious =P )

The important point being that without the where clause the array wouldn't have a name from inside the function body and you could not recursively define.




回答3:


It's mostly a matter of style. Even if they are not exactly equivalent it's not very often that you must use one or the other. Instead it's up to you, and what you think looks nicer.




回答4:


My rule of thumb - if you are defining something at the top level of a function, use "where". If you are defining a helper function which has multiple clauses, definitely use "where". Everywhere else, just pick one!




回答5:


In my experience, where is more readable then let, because it often reads eerily similar to English. For example:

myFun x = aCoefficient * (10 ** anExponent)  
          where aCoefficient = 100 - x  
                anExponent = x - 2  

In English, I'd describe this as "myFun of x is a coefficient times (10 to an exponent), where the coefficient is 100 minus x, and the exponent is x minus 2"




回答6:


Two stylistic advantages of using where:

  • It places the value of the thing you are defining close to its name (and type).

    func x = part1 . part2 (something x)
      where part1 = ...
            part2 = ...
    

    instead of

    func x = let part1 =
                 part2 =
             in part1 . part2 (something x)
    
  • It encourages writing code that can be read "newspaper style" where the important stuff comes first, and all the details come later. That way you can stop reading whenever you feel you don't need to know the rest of the details.

    func x = highlevel1 . highlevel2 (x + 42)
      where highlevel1 = medium (...)
            highlevel2 = medium (...)
    
            medium = ...
    

I mostly use let when the bindings themselves are more interesting than the expression, and they are short. For example when the binding is just to do a pattern match:

func x = let (MyData y _ _) = something in y

This looks better in my opinion than

func x = y
  where (MyData y _ _) = something


来源:https://stackoverflow.com/questions/6032183/where-does-the-where-clause-come-in-handy-in-haskell

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!