gpt4 book ai didi

class - 定义一个函数 a -> String,它适用于没有 Show? 的类型

转载 作者:行者123 更新时间:2023-12-02 21:36:58 26 4
gpt4 key购买 nike

我想定义一个可以“显示”任何类型的值的函数,并对实际定义 Show 实例的类型具有特殊行为:

magicShowCast :: ?

debugShow :: a -> String
debugShow x = case magicShowCast x of
Just x' -> show x'
Nothing -> "<unprintable>"

这将用于在出现问题时向错误消息添加更详细的信息:

-- needs to work on non-Showable types
assertEq :: Eq a => a -> a -> IO ()
assertEq x y = when (x /= y)
(throwIO (AssertionFailed (debugShow x) (debugShow y)))

data CanShow = CanShow1
| CanShow 2
deriving (Eq, Show)

data NoShow = NoShow1
| NoShow2
deriving (Eq)

-- AssertionFailed "CanShow1" "CanShow2"
assertEq CanShow1 CanShow2

-- AssertionFailed "<unprintable>" "<unprintable>"
assertEq NoShow1 NoShow2

有什么办法可以做到这一点吗?我尝试使用 GADT、存在类型和模板 haskell 的各种组合,但要么这些还不够,要么我不知道如何正确应用它们。

最佳答案

真正的答案:你不能。 Haskell 故意没有定义通用的“序列化为字符串”函数,并且在没有某些类型类约束的情况下执行此操作将违反整个城镇的参数化。太可怕了,太可怕了。

如果您不明白为什么这会造成问题,请考虑以下类型签名:

something :: (a, a) -> b -> a

你会如何实现这个功能?通用类型意味着它必须是 const . fstconst . snd , 正确的?嗯。

something (x,y) z = if debugShow z == debugShow y then y else x
> something ('a', 'b') ()
'a'
> something ('a', 'b') 'b'
'b'

Ooooooooops! 能够以任何理智的方式推理你的程序就这么多了。就是这样,show结束了,回家吧,这段时间很有趣。

<小时/>

可怕的、不好的、不明智的答案:当然,如果你不介意无耻地作弊。我是否提到过上面的示例是实际的 GHCi session ?哈哈哈。

import Control.Exception
import Control.Monad
import GHC.Vacuum

debugShow :: a -> String
debugShow = show . nameGraph . vacuumLazy

assertEq :: Eq a => a -> a -> IO ()
assertEq x y = when (x /= y) . throwIO . AssertionFailed $
unlines ["assertEq failed:", '\t':debugShow x, "=/=", '\t':debugShow y]

data NoShow = NoShow1
| NoShow2
deriving (Eq)
> assertEq NoShow1 NoShow2
*** Exception: assertEq failed:
[("|0",["NoShow1|1"]),("NoShow1|1",[])]
=/=
[("|0",["NoShow2|1"]),("NoShow2|1",[])]

哦。好的。这看起来是一个绝妙的想法,不是吗。

无论如何,这并不能完全满足您的需求,因为没有明显的方法可以回退到正确的 Show实例可用时。另一方面,this lets you do a lot more than show can do ,所以也许这是一次洗涤。

不过说真的。不要在实际的工作代码中执行此操作。好的,错误报告、调试、日志记录......这是有道理的。但除此之外,这可能是非常不明智的。

关于class - 定义一个函数 a -> String,它适用于没有 Show? 的类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7005628/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com