Haskell: какая-нибудь функция debugShow? - PullRequest
4 голосов
/ 20 июля 2009

Я хочу использовать Debug.Trace.trace, чтобы напечатать что-то, что, как я знаю, Show. Так же, как я сделал бы в Python и т. Д.

Одним из решений является добавление "Show a =>" к сигнатуре функции, в которую я хочу поместить трассировку, и к любой функции, вызывающей ее и т. Д.

Но было бы намного лучше, если бы я мог использовать некоторую функцию debugShow, которая вызывает show, если значение имеет единицу, в противном случае возвращает "--no show--" или что-то еще.

Вот моя неудачная попытка определить DebugShow (GHC отклоняет "Duplicate instance declarations"):

{-# LANGUAGE FlexibleInstances, UndecidableInstances, OverlappingInstances #-}

class DebugShow a where
  debugShow :: a -> String

instance Show a => DebugShow a where
  debugShow = show

instance DebugShow a where
  debugShow = const "--no show--"

Какой-то «небезопасный бросок» также решил бы мою проблему.

Любой совет?

Примечание. Это только для целей отладки. Я не использую это ни в каком готовом коде.

Ответы [ 4 ]

4 голосов
/ 20 июля 2009

Возможно, вам нужен какой-то вариант:

traceShow :: (Show a) => a -> b -> b
traceShow = trace . show

определено в Debug.Trace

Ограничение "вызовы показывает, если значение имеет единицу, в противном случае возвращает" --no show-- "или что-то другое" трудно ". Я думаю, вам понадобятся перекрывающиеся (и непоследовательные) экземпляры, чтобы определить Show по умолчанию для всех типов (возможно, через unsafeCoerce или через вакуум).

3 голосов
/ 20 июля 2009

Я не совсем уверен в этом, но я думаю, что это невозможно без добавления контекста класса ко всей цепочке вызовов между сайтом использования и сайтом вызовов, где определяется каждая переменная типа. Причина этого заключается в том, что по крайней мере в GHC каждый класс реализован в виде словаря. Поэтому на сайте использования нам нужен словарь Show для a, если он вообще существует. Но чтобы получить это, нам нужно, чтобы он был передан с сайта, где был определен a, а для этого необходимо, чтобы что-то было в сигнатуре всех промежуточных функций.

1 голос
/ 20 июля 2009

«небезопасный бросок» известен как unsafeCoerce. Пожалуйста, соблюдайте предупреждения в его документации ; это простой способ вызвать сбои и другое грязное поведение.

0 голосов
/ 04 октября 2014

Просто используйте реализацию метода по умолчанию в классе DebugShow. Это должно делать именно то, что вы хотите:

{-# LANGUAGE FlexibleInstances    #-}
{-# LANGUAGE UndecidableInstances #-}

class DebugShow a where
  debugShow :: a -> String
  debugShow = const "--no show--"

instance Show a => DebugShow a where
  debugShow = show
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...