Haskell if-конструкция, которая ничего не возвращает на `else` - PullRequest
0 голосов
/ 21 апреля 2020

есть ли способ, в котором такая конструкция (псевдокод):

test (a,b) = if a > 10 then a else null

в Haskell. Если вы отображаете список, я могу использовать filter для этого, но я бы хотел подобную конструкцию, используя if then else.

Ответы [ 4 ]

9 голосов
/ 21 апреля 2020

Haskell не имеет нулевых ссылок, но это не значит, что вы не можете смоделировать наличие или отсутствие значений. Для этого обычно используется тип Maybe с конструкторами данных Just для значений и Nothing вместо нуля.

Вы можете написать свою функцию следующим образом:

test (a,b) = if a > 10 then Just a else Nothing

Вот как с ним взаимодействовать:

Prelude> test (11, "foo")
Just 11
Prelude> test (10, "foo")
Nothing

Тип функции:

test :: (Ord a, Num a) => (a, b) -> Maybe a

Она подчиняется правилу, что и ветвь then и else возвращают значение того же типа - в данном случае тип Maybe a.

2 голосов
/ 21 апреля 2020

Чтобы отфильтровать список с помощью предиката, вы можете просто использовать filter, как это

filter (>10) myList

, но если вы хотите иметь функцию, которая освобождает в выходных данных, если значение было в порядке и возвращает значение , вы можете использовать Maybe тип

test :: Int -> Maybe Int
test a = if a > 10 then Just a else Nothing

, тогда вы можете фильтровать с помощью этой функции, как это

catMaybes 
  $ map test
  $ myList

Но если вы просто хотите отфильтровать список значений, то вы должны использовать первую версию только с предикатом, который возвращает Bool

1 голос
/ 21 апреля 2020

Все ответы хорошие. Я просто хотел бы сделать небольшое дополнение, напомнив, что хотя чистые функции не могут этого сделать, Haskell позволяет нам также выполнять нечистые действия, например, в монаде IO. , Там мы более расслаблены, делая такие вещи.

test :: (Num a, Ord a, Show a) => (a,b) -> IO ()
test (a,b) = when (a < 10) $ print a

λ> test (11,"boru") -- nothing happens
λ> test (9,"boru")
9

вид.

0 голосов
/ 21 апреля 2020

if...else является выражением в Haskell и всегда должно принимать значение. Кроме того, обе ветви должны иметь значение того же типа . Таким образом, ветвь else должна соответствовать тому же типу, что и a, чтобы ваш код работал.

В случае filter результатом должен быть список. Мы можем реализовать filter используя if...else. Идея в том, что если условие истинно, то мы хотим включить элемент в итоговый список. Если нет, то мы хотим продолжить фильтрацию остальной части списка.

filter _ [] = []
filter f (x:xs) = if f x then (x:f xs) else f xs

Обратите внимание, что в обоих случаях результатом является список . Мы удаляем элемент на , не включая его в возвращенный список .

...