DenDragonB / echobot

BSD 3-Clause "New" or "Revised" License
0 stars 0 forks source link

Частичные let-биндинги против IO #2

Closed delfigamer closed 3 years ago

delfigamer commented 3 years ago

https://github.com/DenDragonB/echobot/blob/eab9a733042a38d49c7f2a17892d7791c6c5b244/app/Main.hs#L38-L40

Если TOML.parseTomlDoc в этом месте вернёт ошибку - то вместо того, чтобы напечатать эту ошибку как положено, программа положит её в ленивую подвеску config, и затем свалится во время нормализации условия case:

C:\dev\DenDragon\echobot>stack run
echobot-exe.EXE: app\Main.hs:38:9-75: Non-exhaustive patterns in Right toml

В ленивости можно убедиться, если между let Right toml = ... и case config of вставить какое-нибудь промежуточное IO-действие. По-хорошему, такие ошибки следует обрабатывать явно, например, через явное бросание IO-исключения:

toml <-
  either fail pure $
    TOML.parseTomlDoc "" $ T.pack $ tUserConf ++ tMainConf
config <-
  either fail pure $
    (Aeson.eitherDecode $ Aeson.encode toml :: Either String Config)

Если нас не интересует содержание альтернативных конструкторов, а требуется именно провести частичный паттерн-матчинг (не в этом конкретном случае) - это тоже лучше делать через монаду:

Right toml <- pure $ TOML.parseTomlDoc "" $ T.pack $ tUserConf ++ tMainConf

В этом случае, паттерн-матчинг не отложится в ленивой подвеске, а произойдёт в момент исполнения этого действия в монаде. Можно сказать, что момент нормализации результата TOML.parseTomlDoc - это левая стрелка на этой же строке, а не первое использование где-нибудь в будущем.

ghost commented 3 years ago
 let config = Aeson.eitherDecode $ Aeson.encode toml :: Either String Config 

Зачем это вообще нужно? Зачем энкодить а потом декодить?

DenDragonB commented 3 years ago

Исправил, заодно перешел на YAML

delfigamer commented 3 years ago

https://github.com/DenDragonB/echobot/blob/a525157b430b98ee3efac6d5e2199b50ce171d49/app/Main.hs#L37 Последняя строка mainconf и первая строка userconf тут сольются в одну. Если в mainconf последняя строка - пустая, то будет незаметно, но противном случае - будут сюрпризы. Чтобы такого не было, между файлами нужно вставить дополнительный перевод строки.

DenDragonB commented 3 years ago

Добавил