Получить значение Maybe в Haskell

Я реализую функцию myFunction, которая использует anotherFunction.

anotherFunction - внешняя функция, которую нельзя изменить. Возвращает значение типа Maybe.

myFunction - это рекурсивная функция, которая проверяет, является ли значение, возвращаемое другим myFunction, значением Just или Nothing. Если это Nothing, тогда верните Nothing, в противном случае он будет использовать чистое значение, возвращаемое myFunction в качестве аргумента anotherFunction.

В основном примерно так:

--These cannot be modified

data A = B | F a

anotherFunction :: x -> Maybe x
--Something here

myFunction :: A -> Maybe x 

--These can be modified
myFunction (F a) = {- if (myFunction a == Nothing) 
                        then Nothing 
                        else anotherFunction (pure value of (myFunction a)) -}

Как этого добиться?


person user3545752    schedule 12.10.2015    source источник
comment
Используйте оператор case.   -  person user1937198    schedule 12.10.2015
comment
в Haskell обычные функции (не конструкторы) обычно начинаются с нижнего регистра.   -  person jakubdaniel    schedule 12.10.2015
comment
Мало того, что они обычно начинаются со строчных букв, они должны начинаться со строчных букв, чтобы это было разрешено в Haskell. Я соответствующим образом отредактировал вопрос. - - (В принципе, нижнее подчеркивание также допускается в качестве первого символа имени переменной, но не делайте этого - подчеркивание имеет особое значение.   -  person leftaroundabout    schedule 12.10.2015


Ответы (3)


Вы можете сопоставить значение, возвращаемое из MyFunction, используя case:

case (myFunction a) of
  Nothing -> Nothing
  Just x -> anotherFunction x

однако более кратким методом является использование >>=:

(>>=) :: Maybe a -> (a -> Maybe b) -> Maybe b
myFunction (f a) = (myFunction a) >>= anotherFunction

или вы можете использовать обозначение do:

myFunction (f a) = do
  x <- myFunction a
  anotherFunction x
person Lee    schedule 12.10.2015

Вы не сможете использовать ==, если у вас нет ограничения Eq a => Maybe a в подписи. Лучший способ сделать это - использовать инструкцию case:

case m of
    Just x -> anotherFunction x
    Nothing -> Nothing

Этот шаблон настолько распространен для Maybe, что образует экземпляр Monad для Maybe, предоставляя вам функции return x = Just x и f >>= x = case x of Just a -> f a; Nothing -> Nothing.

person C. Quilley    schedule 12.10.2015
comment
Не называй это maybe. Это имя функции в Prelude. - person Zeta; 12.10.2015
comment
@Zeta Спасибо, изменилось. - person C. Quilley; 12.10.2015

Предположим, у вас есть f и g, которые оба производят значения, упакованные в тип Maybe (Just 3, Just "three", Nothing). Вы можете составить два вида:

import Control.Monad

f :: a -> Maybe b -- suppose these two are signatures of the given two functions
g :: b -> Maybe c

h :: a -> Maybe c -- this is the way you pass values from one
h = f >=> g       -- to the other and bail out when you see Nothing

Я использовал удобные имена для типов a, b и c, чтобы сделать композицию более ясной, но обратите внимание, что типы не являются ограничивающими, и a в одной подписи не имеет ничего общего с a в другой подписи, фактический тип определяется, когда эти две функции используются в конкретном контексте.

Поскольку вы, похоже, не накладываете никаких ограничений на то, что такое a в F a конструкторе, я полагаю, вы хотите, чтобы он отличался от A. В этом случае функция myFunction не может иметь тип A -> ..., потому что вы пытаетесь передать a в качестве аргумента.

person jakubdaniel    schedule 12.10.2015