Closed delfigamer closed 3 years ago
let config = Aeson.eitherDecode $ Aeson.encode toml :: Either String Config
Зачем это вообще нужно? Зачем энкодить а потом декодить?
Исправил, заодно перешел на YAML
https://github.com/DenDragonB/echobot/blob/a525157b430b98ee3efac6d5e2199b50ce171d49/app/Main.hs#L37 Последняя строка mainconf и первая строка userconf тут сольются в одну. Если в mainconf последняя строка - пустая, то будет незаметно, но противном случае - будут сюрпризы. Чтобы такого не было, между файлами нужно вставить дополнительный перевод строки.
Добавил
https://github.com/DenDragonB/echobot/blob/eab9a733042a38d49c7f2a17892d7791c6c5b244/app/Main.hs#L38-L40
Если
TOML.parseTomlDoc
в этом месте вернёт ошибку - то вместо того, чтобы напечатать эту ошибку как положено, программа положит её в ленивую подвескуconfig
, и затем свалится во время нормализации условия case:В ленивости можно убедиться, если между
let Right toml = ...
иcase config of
вставить какое-нибудь промежуточное IO-действие. По-хорошему, такие ошибки следует обрабатывать явно, например, через явное бросание IO-исключения:Если нас не интересует содержание альтернативных конструкторов, а требуется именно провести частичный паттерн-матчинг (не в этом конкретном случае) - это тоже лучше делать через монаду:
В этом случае, паттерн-матчинг не отложится в ленивой подвеске, а произойдёт в момент исполнения этого действия в монаде. Можно сказать, что момент нормализации результата
TOML.parseTomlDoc
- это левая стрелка на этой же строке, а не первое использование где-нибудь в будущем.