gpt4 book ai didi

haskell - 显示 a 可能已经是字符串的实例

转载 作者:行者123 更新时间:2023-12-02 07:06:19 24 4
gpt4 key购买 nike

我正在研究一种类型,它是一个基本上可以包含任何东西的容器。像这样的事情:

data Foo a = Foo [a]

我正在开发这种类型的 Show 实例。

instance (Show a) => Show (Foo a) where
show (Foo x) = concat $ map show x

这工作正常:

show (Foo [1,2,3]) -- creates the string "123"
show (Foo [True, False]) -- creates the string "TrueFalse"

但是,有时 foo 中包含的“a”已经是一个字符串,因此调用“map show x”是不必要的。对字符串调用 show 的结果是在字符串周围放置“”。

show (Foot ["A", "B"]) -- creates the string ""A""B""
-- what I'd like is the string "AB"

有没有办法为(Foo String)定义一个单独的 Show 实例?

最佳答案

你不能在标准 Haskell 中做这种事情。这是可以做到的,但是需要一些编译器黑魔法。我们将使用一些 GHC 扩展。

{-# LANGUAGE FlexibleInstances #-}

data Foo a = Foo [a]

instance (Show a) => Show (Foo a) where
show (Foo x) = concat $ map show x

instance {-# OVERLAPS #-} Show (Foo String) where
show (Foo x) = concat x

FlexibleInstances 让我们打破通常的实例规则并编写 Show (Foo String),而通常我们只能编写 Show (Foo a) 。然后,我们用 {-# OVERLAPS #-} 注释前者,以抑制当 Show (Foo a) 有多个重叠实例时发生的编译器错误。编译器足够聪明,可以选择更具体的实例,因此 Foo String 将始终调用第二个实例,而 Foo a 则用于任何其他 a code> 将调用第一个。

使用示例:

*Main> Foo [1, 2, 3]
123
*Main> Foo [True, False]
TrueFalse
*Main> Foo ["A", "B"]
AB

这样的风格好吗?可能不会。我建议重新考虑您的策略,并为字符串大小写提供不同的函数(例如 showFooString),因为像我们上面所做的那样编写代码可能会让用户感到困惑。但如果你真的认为这是做你想做的事情的最佳方式,那就去做吧。请记住,您的代码实际上只能使用 GHC 进行编译。

关于haskell - 显示 a 可能已经是字符串的实例,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51233160/

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