Паттерн Хаскелла, соответствующий симметричным случаям - PullRequest
8 голосов
/ 11 мая 2011

Предположим, у меня есть выражение haskell, например:

foo (Nothing, Just a) = bar a
foo (Just a, Nothing) = bar a

Существует ли какой-либо синтаксис haskell, чтобы свернуть эти случаи, чтобы я мог сопоставить любой шаблон и указать bar a в качестве ответа для обоих?Или это настолько кратко, насколько я могу это понять?

Ответы [ 3 ]

8 голосов
/ 11 мая 2011

Если ваш код более сложный, чем ваш пример, вы можете сделать что-то подобное, используя экземпляр Alternative для Maybe и расширение PatternGuards (часть Haskell2010).

{-# LANGUAGE PatternGuards #-}
import Control.Applicative

foo (x, y) | Just a <- y <|> x = bar a

В случае, если вы не знакомы с ним, <|> выбирает крайний левый Just, если он есть, и возвращает Nothing в противном случае, вызывая сбой охраны шаблона.

5 голосов
/ 11 мая 2011

Это так же кратко, как и в Хаскеле. В ML есть синтаксис для того, что вы хотите (путем написания нескольких шаблонов, которые связывают одни и те же переменные рядом друг с другом, разделенные | телом после последнего шаблона), но в Haskell это не так.

4 голосов
/ 12 мая 2011

Вы можете использовать -XViewPatterns, чтобы добавить произвольные функции, чтобы свести два ваших случая в один шаблон. Ваш шаблон теперь является функцией p, которая выдает то, что вы хотите сопоставить:

foo (p -> (Just a, Nothing)) = bar a

намного проще!

Мы должны определить p как:

p (Nothing, a@(Just _)) = (a, Nothing)
p a@(Just _,   Nothing) = a
p a                     = a

или как вы хотите нормализовать данные перед просмотром.


Ссылки: Глава Руководства пользователя GHC по представлению о шаблонах

...