Хаскель охраняет лямбда-функции? - PullRequest
43 голосов
/ 05 августа 2010

Можно ли установить охрану лямбда-функций?

Например:

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

Ответы [ 5 ]

51 голосов
/ 05 августа 2010

Неа. Ближайший прямой перевод похож на

\k -> case () of
       _ | k < 0     -> "negative"
         | k == 0    -> "zero"
         | otherwise -> "positive"
46 голосов
/ 18 сентября 2012

Начиная с GHC 7.6.1 существует расширение под названием MultiWayIf, которое позволяет написать следующее:

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

На которое, по меньшей мере, приятнее смотретьчем альтернатива, использующая case.

Для сопоставления с образцом существует соответствующее расширение, называемое LambdaCase:

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

Эти расширения, однако, не являются частью стандартного Haskell, инеобходимо включить явно с помощью прагмы {-# LANGUAGE LambdaCase #-} или {-# LANGUAGE MultiWayIf #-} в верхней части файла или путем компиляции с флагом -XLambdaCase или -XMultiWayIf.

27 голосов
/ 05 августа 2010

Мне нравится, чтобы лямбды были короткими и сладкими, чтобы не нарушать визуальный поток читателя. Для функции, определение которой синтаксически достаточно громоздко, чтобы оправдать охранников, почему бы не вставить ее в предложение where?

showSign k = mysign ++ " (" ++ show k ++ ")"
  where
  mysign
    | k < 0     = "negative"
    | k == 0    = "zero"
    | otherwise = "positive"
7 голосов
/ 27 февраля 2016

Элегантный и лаконичный способ сделать это с LambdaCase:

{-# LANGUAGE LambdaCase #-}

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

или

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

Случай, когда я использовал его, чтобы поймать ошибку EOF:

{-# LANGUAGE ScopedTypeVariables #-}

o <- hGetContents e `catch` (\case (e :: IOException) | isEOFError e -> return "")
0 голосов
/ 23 апреля 2019

Еще один способ использует комбинацию расширений LambdaCase и ViewPatterns GHC:

{-# LANGUAGE LambdaCase, ViewPatterns #-}

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

Это избавляет вас от необходимости называть промежуточную переменную.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...