Search
Write a publication
Pull to refresh
31
0
Берестов Данил @goosedb

Пишу на Haskell

Send message

А Вы точно читали этот текст дальше наброса на раст?

Наверное, я как-то криво выразился. Не нужно композить два чёрных ящика (box Error, с anyhow::Error). Нужно композить два белых (конкретные Result<FooError, _>, Result<BarError, _>) в один чёрный. И как только вы это сделали, объединили Result<FooError, T> с Result<BarError, T> в Result<anyhow::Error, T>, вы потеряли вообще всю информацию, какие конкретно ошибки могут там быть. Это всё равно, что хаскелевый SomeException

Можно для конкретики пример, когда оно там не работает транзитивно?

Так ето ты скопипасти, да проверь, что оно неюзабельно, куда ни добавляй)

Можно equational constraint добавить

А куда ты его добавишь-то?

Я, кстати, не вижу фундаментальных причин, по которым HasCatch из capability

Функциональные зависимости всё портят. Хотя в этом случае я даже не особо понимаю, как оно там считается

data Foo = Foo deriving (Show, Exception)
data Bar = Bar deriving (Show, Exception)

throwCap :: forall a m b. Cap.HasThrow a a m => a -> m b 
throwCap = Cap.throw @a

type CanThrow a = Cap.HasThrow a a

foo :: (CanThrow Bar m, CanThrow Foo m) => m ()
foo = do
  () <- throwCap Foo
  throwCap Bar

catchCap :: (Unlift.MonadUnliftIO m, Exception e) => Cap.MonadCatch e m a -> (e -> m a) -> m a
catchCap (Cap.MonadCatch m) = Unlift.catch m

baz :: CanThrow Bar m => m ()
baz = foo `catchCap` \Foo -> pure ()
    • Couldn't match type ‘Foo’ with ‘Bar’
        arising from a functional dependency between:
          constraint ‘HasThrow Bar Bar (MonadCatch Foo m)’
            arising from a use of ‘foo’
          instance ‘HasThrow tag e (MonadCatch e m1)’ at <no location info>
    • In the first argument of ‘catchCap’, namely ‘foo’
      In the expression: foo `catchCap` \ Foo -> pure ()
      In an equation for ‘baz’: baz = foo `catchCap` \ Foo -> pure ()
    |
xxx | baz = foo `catchCap` \Foo -> pure ()
    |       ^^^

Проблема Result в том, что когда они используется, как есть (без box Error, failure, anyhow), то он не композится с другими Result. Именно поэтому и придумали failure и anyhow. Однако их проблема уже в другом. Как только ты забоксил ошибку в трейт Error (или обернул в anyhow::Error), ты понятия не имеешь, что за ошибка лежит внутри. Два стула: либо не композится, как MonadError/ExceptT либо неизвестность, как с голыми исключениями.

Да, так сделать можно (я про Named), я пробовал. Но типы становятся слишком вербозными и чаще бесполезными, чем полезными.

Information

Rating
Does not participate
Location
Москва, Москва и Московская обл., Россия
Date of birth
Registered
Activity