Функция Haskell возвращает только пару значений, если оба аргумента равны Just, иначе ничего

Определить функцию

   pairMaybe :: Maybe a -> Maybe b -> Maybe (a,b)

который дает результат Just, только если оба аргумента равны Just, и Nothing, если любой из аргументов равен Nothing.

Я придумал:

pairMaybe (Just a) (Just b) = Just (a,b)
pairMaybe (Just a) Nothing = Nothing
pairMaybe Nothing (Just b) = Nothing

Я не уверен, что это правильный способ написания. Что-то не так с этим или это способ определить эту функцию?

Также я думаю, что мне, вероятно, хотелось бы лучшего объяснения того, что эта функция на самом деле может делать, поэтому, если я вызову pairMaybe с двумя аргументами, какие это могут быть аргументы? Конечно, они должны быть типа Maybe, но какой хороший пример?


person Suzan Aydın    schedule 29.11.2013    source источник
comment
Если вы хотите знать, работает код или нет, вы можете ввести его в файл и загрузить его в GHCi с помощью :load yourfile.hs и протестировать функцию самостоятельно. Если вы запрашиваете обзор кода (то есть мнение экспертов и предложения по улучшению), вы, к сожалению, оказались не на том сайте! Возможно, вам повезет больше на codereview.SE.   -  person kqr    schedule 30.11.2013
comment
Я знаю, как проверить, работает ли код, и он работает, но я больше думаю о том, для чего он на самом деле предназначен, а не о том, компилируется он или нет.   -  person Suzan Aydın    schedule 30.11.2013


Ответы (3)


Делать это с помощью сопоставления с образцом — это нормально; вы можете упростить свой код, используя

pairMaybe :: Maybe a -> Maybe b -> Maybe (a,b)
pairMaybe (Just a) (Just b) = Just (a,b)
pairMaybe _        _        = Nothing

При этом ваша функция на самом деле просто поднимает функцию (,) (которая создает 2-кортежи) в монаду Maybe, поэтому вы также можете написать

pairMaybe :: Maybe a -> Maybe b -> Maybe (a,b)
pairMaybe = liftM2 (,)
person Frerich Raabe    schedule 29.11.2013
comment
Кроме того, есть идеи, как это будет проверено? Я пробовал что-то вроде парыMaybe 5 6, но если жалуется на это, он не может вывести типы... - person Suzan Aydın; 30.11.2013
comment
@SuzanAydın: Ну, pairMaybe 5 6 не печатает проверку, вы, вероятно, имели в виду pairMaybe (Just 5) (Just 6). При этом обязательно включите сигнатуру типа, если вы используете версию на основе liftM2, иначе компилятор не сможет решить, какую сигнатуру типа вывести. - person Frerich Raabe; 30.11.2013

Вы пропустили шаблон, в котором оба значения равны Nothing (это не соответствует ни одному из ваших шаблонов):

pairMaybe Nothing Nothing = Nothing

Помимо этого сопоставление с образцом — отличный способ добиться цели в Haskell.

person Simeon Visser    schedule 29.11.2013
comment
Эй, глупо, что я забыл об этом... но кроме этого это действительно нормально? :) Извините, я немного шокирован, новичок в хаскеле. - person Suzan Aydın; 30.11.2013
comment
@SuzanAydın: С этим дополнением все совершенно правильно, хотя на самом деле вам нужны только два случая: pairMaybe (Just a) (Just b) и pairMaybe _ _ — поскольку все остальные случаи дают один и тот же результат, вы можете просто объединить их вместе. - person Chuck; 30.11.2013
comment
@SuzanAydın да, мне кажется, все в порядке. Я думаю, что pairMaybe можно использовать для проверки наличия двух значений и, если нет, перейти к Nothing. - person Simeon Visser; 30.11.2013

Выглядит отлично! Хотя можно немного сократить.

pairMaybe (Just a) (Just b) = Just (a,b)
pairMaybe _        _        = Nothing

Это также исправляет ошибку, на которую указал Симеон. Причина, по которой вы можете упростить это, заключается в том, что все правые части с Nothing одинаковы, поэтому эти случаи можно объединить в один.

person Tarrasch    schedule 29.11.2013