Как сгенерировать исключение с CallStack? - PullRequest
0 голосов
/ 02 января 2019

У меня есть тип исключения UnknownException, который я хотел бы включить в вызов CallStack.

module Main where

import Control.Exception (Exception, throw)

newtype UnknownException = UnknownException
  { caller :: String
  } deriving (Show)

instance Exception UnknownException

main :: IO ()
main = willThrow

willThrow :: IO ()
willThrow = throw $ UnknownException "willThrow"

Я бы хотел, чтобы приведенный выше пример печатал журналы, подобные этому

example-exe: UnknownException {caller = "willThrow"}
CallStack (from HasCallStack):
  willThrow, called at app/Main.hs:16:13 in main:Main
  main, called at app/Main.hs:13:8 in main:Main

но на самом деле напечатано:

example-exe: UnknownException {caller = "willThrow"}

Также, является ли хорошей практикой включать CallStack в исключения в Haskell?

1 Ответ

0 голосов
/ 02 января 2019

Да, я думаю, что это хорошая практика.Если вы компилируете с профилированием, вы можете просто использовать

currentCallStack :: IO [String]

из GHC.Stack.Обратите внимание, что он в IO, но я бы посоветовал unsafePerformIO, если вы выдадите ошибку, если вы в чистом коде.Поскольку все основания равны по смыслу, на самом деле нет никаких нарушений чистоты.

Но если вы хотите получать стеки вызовов без профилирования (скажем, вы хотите включить его в сообщение журнала при производстве), вам необходимосделать больше.Вы должны включать ограничения HasCallStack везде, где вы хотите, чтобы о стеке сообщалось.Так что

main :: IO ()
main = print f

f :: Int
f = g

g :: HasCallStack => Int
g = h

h :: HasCallStack => Int
h = error (show callStack)

сообщит о стеке вызовов до g, но пропустит f.К сожалению,

Если в области действия нет CallStack и определение включения имеет явную сигнатуру типа, GHC решит ограничение HasCallStack для одноэлементного CallStack, содержащего только текущий сайт вызова.

Это означает, что он пропустит всех вызывающих абонентов f, даже если они имеют HasCallStack только потому, что f не имеет такого ограничения.Я нахожу это ужасно громоздким.Это довольно недавняя функция, поэтому я надеюсь, что команда GHC имеет в виду что-то лучшее, что они используют это, чтобы двигаться в направлении.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...