简体   繁体   English

Haskell 保护 lambda 函数?

[英]Haskell guards on lambda functions?

Is it possible to have guards on lambda functions?是否可以对 lambda 函数进行保护?

For example:例如:

\k
    | k < 0     -> "negative"
    | k == 0    -> "zero"
    | otherwise -> "positive"

Other answers show how the extensions LambdaCase and MultiWayIf , introduced since this answer was first written, can solve this.其他答案显示了自首次编写此答案以来引入的扩展LambdaCaseMultiWayIf如何解决此问题。 Without them, the nearest direct translation is something a bit like没有它们,最近的直接翻译有点像

\k -> case () of
       _ | k < 0     -> "negative"
         | k == 0    -> "zero"
         | otherwise -> "positive"

As of GHC 7.6.1 there is an extension called MultiWayIf that lets you write the following:GHC 7.6.1 开始,有一个名为MultiWayIf的扩展,可让您编写以下内容:

\k -> if
  | k < 0     -> "negative"
  | k == 0    -> "zero"
  | otherwise -> "positive"

Which at the very least is more pleasant to look at than the alternative using case .这至少比替代用case更令人愉快。

For pattern-matching, there is a related extension called LambdaCase :对于模式匹配,有一个名为LambdaCase的相关扩展:

\case
  "negative" -> -1
  "zero"     -> 0
  "positive" -> 1
  _          -> error "invalid sign"

These extensions are not part of standard Haskell, though, and need to be enabled explicitly via a {-# LANGUAGE LambdaCase #-} or {-# LANGUAGE MultiWayIf #-} pragma at the top of the file, or by compiling with the flag -XLambdaCase or -XMultiWayIf .但是,这些扩展不是标准 Haskell 的一部分,需要通过文件顶部的{-# LANGUAGE LambdaCase #-}{-# LANGUAGE MultiWayIf #-}编译指示显式启用,或者通过编译标志-XLambdaCase-XMultiWayIf

I like to keep lambdas short and sweet so as not to break the reader's visual flow.我喜欢让 lambdas 简短而甜蜜,以免破坏读者的视觉流程。 For a function whose definition is syntactically bulky enough to warrant guards, why not stick it in a where clause?对于一个定义在语法上足够庞大以保证保护的函数,为什么不把它放在一个where子句中呢?

showSign k = mysign ++ " (" ++ show k ++ ")"
  where
  mysign
    | k < 0     = "negative"
    | k == 0    = "zero"
    | otherwise = "positive"

An elegant and concise way to do it with LambdaCase:使用 LambdaCase 执行此操作的优雅而简洁的方法:

{-# LANGUAGE LambdaCase #-}

\case k | k < 0     -> "negative"
        | k == 0    -> "zero"
        | otherwise -> "positive"

or或者

\case
  k | k < 0     -> "negative"
    | k == 0    -> "zero"
    | otherwise -> "positive"

A case when I used it, to catch an EOF error:我使用它时的一个案例,用于捕获 EOF 错误:

{-# LANGUAGE ScopedTypeVariables #-}

o <- hGetContents e `catch` (\case (e :: IOException) | isEOFError e -> return "")

Yet another way uses a combination of the LambdaCase and ViewPatterns GHC extensions:另一种方法是结合使用LambdaCaseViewPatterns GHC 扩展:

{-# LANGUAGE LambdaCase, ViewPatterns #-}

\case
    ((< 0) -> True) -> "negative"
    ((==0) -> True) -> "zero"
    _               -> "positive"

This keeps you from having to name an intermediate variable.这使您不必命名中间变量。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM