Как создать собственную монаду синтаксического анализатора для SimpleJSON в PureScript?

У меня есть следующее, которое работает до тех пор, пока я не пытаюсь определить readJSON':

newtype JSONWithErr a = JSONWithErr (Writer (Array Foreign.ForeignError) a)

derive newtype instance jsonWithErrApply :: Apply JSONWithErr
derive newtype instance jsonWithErrApplicative :: Applicative JSONWithErr
derive newtype instance jsonWithErrFunctor :: Functor JSONWithErr
derive newtype instance jsonWithErrBind :: Bind JSONWithErr
derive newtype instance jsonWithErrMonad :: Monad JSONWithErr
derive newtype instance jsonWithErrTell :: MonadTell (Array Foreign.ForeignError) JSONWithErr
derive newtype instance jsonWithErrWriter :: MonadWriter (Array Foreign.ForeignError) JSONWithErr

newtype JSONParse a = JSONParse (ExceptT (NonEmptyList ForeignError) JSONWithErr a)

derive newtype instance jsonParseApply :: Apply JSONParse
derive newtype instance jsonParseApplicative :: Applicative JSONParse
derive newtype instance jsonParseFunctor :: Functor JSONParse
derive newtype instance jsonParseBind :: Bind JSONParse
derive newtype instance jsonParseMonad :: Monad JSONParse
derive newtype instance jsonParseTell :: MonadTell (Array Foreign.ForeignError) JSONParse
derive newtype instance jsonParseWriter :: MonadWriter (Array Foreign.ForeignError) JSONParse
derive newtype instance jsonParseThrow :: MonadThrow (NonEmptyList ForeignError) JSONParse

generalize :: forall m a. Monad m => Identity a -> m a
generalize = unwrap >>> pure

-- type Except e = ExceptT e Identity
genExcept :: forall m e a. Monad m => ExceptT e Identity a -> ExceptT e m a
genExcept = unwrap >>> generalize >>> ExceptT

readJSON' :: forall a. JSON.ReadForeign a => String -> JSONParse a
readJSON' s = JSONParse $ genExcept $ (pure >>> JSONWithErr) <$> (JSON.readJSON' s) -}

Ошибка здесь, которая охватывает все определение readJSON', такова:

Could not match type

    JSONWithErr t2

  with type

    a0


while trying to match type JSONParse t1
  with type JSONParse a0
while checking that expression (apply JSONParse) ((apply genExcept) ((map (...)) (readJSON' s)))
  has type JSONParse a0
in value declaration readJSON'

where a0 is a rigid type variable
        bound at (line 0, column 0 - line 0, column 0)
      t1 is an unknown type
      t2 is an unknown type

Я попытался немного упростить его, но, похоже, у меня возникли проблемы с ограничениями; в следующем упрощении типизированная дыра не работает из-за более ранней ошибки:

tmp :: forall a. JSON.ReadForeign a => String -> ExceptT (NonEmptyList ForeignError) JSONWithErr a
tmp s = ?help (JSON.readJSON' s)

И ошибка:

  No type class instance was found for

    Simple.JSON.ReadForeign t0

  The instance head contains unknown type variables. Consider adding a type annotation.

while applying a function readJSON'
  of type ReadForeign t0 => String -> ExceptT (NonEmptyList ForeignError) Identity t0
  to argument s
while inferring the type of readJSON' s
in value declaration tmp

Какая у вас ошибка readJSON'?

Fyodor Soikin 24.12.2020 03:31

Извиняюсь за упущение, обновлено

bbarker 24.12.2020 04:31
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
2
84
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Я думаю, вы просто запутались в собственной сообразительности.

Посмотрите, какой тип аргумента genExcept ожидает: ExceptT e Identity a, но вы также можете сказать, что e ~ (NonEmptyList ForeignError), потому что результат genExcept позже оборачивается в JSONParse

Таким образом, тип аргумента, который ожидает genExcept, как инстанцированный в теле readJSON', — это ExceptT (NonEmptyList ForeignError) Identity a, для которого есть удобный псевдоним типа — F.

Итак, мы можем сказать, что это должно быть:

(pure >>> JSONWithErr) <$> (JSON.readJSON' s) :: F a

Но посмотрите на возвращаемый тип JSON.readJSON':

readJSON' :: forall a. ReadForeign a => String -> F a

Так что JSON.readJSON' s уже типа F a

А затем вы оборачиваете его в какой-то pure, а затем в JSONWithErr, так что все выражение становится таким:

(pure >>> JSONWithErr) <$> (JSON.readJSON' s) :: F (JSONWithErr (b a))

для некоторых b определяется pure.

Чего genExcept не ожидает. Так что вполне естественно вы получаете ошибку.

Из того, что я могу предположить о ваших конечных намерениях, кажется, что вы можете передать JSON.readJSON' s напрямую в genExcept, и типы сработают:

readJSON' :: forall a. JSON.ReadForeign a => String -> JSONParse a
readJSON' s = JSONParse $ genExcept $ JSON.readJSON' s

Джордж, мне грустно, что я пропустил это, но рад, что решение было столь же разумным, как и все это. Я думаю, что изначально я настроил это выражение, а затем был убежден, что мне нужно что-то подобное, и никогда полностью не пересматривал типы, с которыми имел дело.

bbarker 27.12.2020 21:17

Другие вопросы по теме