аргумент runMaybeT of MaybeT - PullRequest
       5

аргумент runMaybeT of MaybeT

2 голосов
/ 04 августа 2020

В https://en.wikibooks.org/wiki/Haskell/Monad_transformers, я вижу

newtype MaybeT m a = MaybeT { runMaybeT :: m (Maybe a) }

, а затем создание MaybeT как монады:

instance Monad m => Monad (MaybeT m) where
  return  = MaybeT . return . Just

  -- The signature of (>>=), specialized to MaybeT m:
  -- (>>=) :: MaybeT m a -> (a -> MaybeT m b) -> MaybeT m b
  x >>= f = MaybeT $ do maybe_value <- runMaybeT x
                        case maybe_value of
                           Nothing    -> return Nothing
                           Just value -> runMaybeT $ f value

Я не понимаю аргумент x в runMaybeT x. Разве runMaybeT не должен принимать аргумент, соответствующий a? Но вместо этого дается x, что является всей MonadT монадой

Ответы [ 2 ]

3 голосов
/ 04 августа 2020

Это просто стандартный синтаксис записи. В таком определении типа, как

data Foo = Foo { a :: Int, b :: String }

, вероятно, вас не удивит, что мы автоматически получаем функции a :: Foo -> Int и b :: Foo -> String.

Для MaybeT это абсолютно не отличается. (Он использует newtype, а не data, но здесь это не имеет значения, то же самое было бы, если бы вместо него использовалось определение data)

newtype MaybeT m a = MaybeT { runMaybeT :: m (Maybe a) }

это дает нам функцию runMaybeT :: MaybeT m a -> m (Maybe a) по той же причине, по которой мы получаем функции a и b в более простом примере выше. Это просто то, что делает синтаксис записи.

В частности, в этом случае, как всегда с newtype, определенным с использованием синтаксиса записи, функция runMaybeT позволяет нам «развернуть» значение c монади, начиная с от абстрактного MaybeT m a к более "конкретному" представлению как значение типа m (Maybe a).

Это используется в реализации >>= для MaybeT m: поскольку его первый аргумент (x в вашем фрагменте) имеет тип MaybeT m a, нам сначала нужно runMaybeT, чтобы получить «развернутое» значение типа m (Maybe a), а затем использовать >>= из «базовой монады» m (показано здесь с do обозначение), чтобы «извлечь» значение типа Maybe a, которое затем сопоставляется с шаблоном обычным способом.

2 голосов
/ 04 августа 2020

runMaybeT - это геттер . Это функция, которая принимает объект MaybeT m a и возвращает объект m (Maybe a), поэтому у него есть подпись MaybeT m a -> m (Maybe a).

Возможно, это будет легче понять, если мы распакуем значение с помощью шаблона:

instance Monad m => Monad (MaybeT m) where
  return  = MaybeT . return . Just
  <b>MaybeT rm</b> >>= f = MaybeT $ do
                        maybe_value <- <b>rm</b>
                        case maybe_value of
                            Nothing -> return Nothing
                            Just value -> runMaybeT $ f value
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...