Debugging 在Show实例中使用Hood

Debugging 在Show实例中使用Hood,debugging,haskell,Debugging,Haskell,如何使用从Show with Debug.Observe.Observe派生的任何用户数据类型 data MyData = Foo | Bar deriving (Show) myFunc = consumMyData . observe "Debug: " . produceMyData consumMyData :: MyData -> ... produceMyData :: ... -> MyData main = runO $ myFunc 所以我可以避免写: ins

如何使用从Show with Debug.Observe.Observe派生的任何用户数据类型

data MyData = Foo | Bar deriving (Show)

myFunc = consumMyData . observe "Debug: " . produceMyData
consumMyData :: MyData -> ...
produceMyData :: ... -> MyData

main = runO $ myFunc
所以我可以避免写:

instance Observable MyData where
    observer my = send (show my) (return my)
一直以来,我只需要数据名

可观察实例仅为所有标准数据类型定义,但不包括Show

或者如果我有这样的事情:

unshow :: Unshow a => String -> a
我可以做到:

myFunc consumMyData . unshow . oberserve "Debug: " . show . produceMyData

首先,我强烈建议您提供所有必要的可观察实例。您可以使用,它直接支持Observable,或者自动派生实例,这样您就不需要自己编写它们

替代品就没那么美味了

unshow :: Unshow a => String -> a
这是由
Read
类提供的。单个操作是
read
,它与您给定的类型完全相同。函数
read
show
应该是反向的,以便
读取。show
相当于
id
。大多数标准数据类型都提供
读取
,尽管第三方库可能不提供

这将比可观察实例的效率低得多,因为每次观察数据时,都会对所有数据进行反序列化。如果你有任何重要的数据,这将是一个巨大的打击

另一种选择是为每种类型创建一个可观察的实例

同样,这并不意味着“当'a'是Show的成员时,使用这个可观察的实例”。它意味着“对所有事情都使用这个可观察的实例,如果范围中没有Show实例,这就是一个错误”。这需要大量略显粗略的扩展,并导致实例重叠的问题

如果你足够关心使用Hood,我不明白你为什么想要这个实例

编辑:

类型转换似乎有一个 高于函数的优先级 应用:
putStrLn。显示$read
“Foo”::MyData——错误putStrLn。显示
$(读“Foo”::MyData)

这是一个相当普遍的问题。考虑函数:

f1 :: String -> String
f1 = show . read
GHC不允许这样<代码>读取::读取a=>String->a和
show::show a=>a->String

但是,当您将两者结合起来时,GHC无法确定实例化
a
type变量的类型。换句话说,你有一个字符串,你反序列化它,然后重新序列化它,但是你反序列化到什么类型?您需要通过对read或show使用显式类型签名来告诉GHC,这就是您的第二个示例所做的。这不是类型转换,而是您编写了类型推理器在没有帮助的情况下无法理解的代码。

I类型转换的优先级似乎高于函数application:putStrLn。显示$read“Foo”::MyData——错误putStrLn。show$(read“Foo”::MyData)有时使用“read.observe.show”比使用实例类更容易,尤其是在性能不是问题的情况下。但是“instance show a=>Observable a”不是吗仅限制在模块范围内显示实例的使用情况?此实例意味着您只能在范围内使用具有显示实例的类型进行观察,但类型检查器仍然认为它是所有类型的有效实例。类上下文直到过程的最后才对类型检查或推断产生影响。类似于“observeShow::Show a=>String->a->a”这样的“which forces”(Show my)”但仅返回“my”,并且仅当“my”实际被使用时才返回,之前的注释被删除。这个函数怎么样?
observeShow a=send(show a)(return a)
?未经测试,但它应该可以工作。当然,只有当您可以直接调用函数时,它才会工作,而不是当您需要一个可观察的实例时。
f1 :: String -> String
f1 = show . read