【问题标题】:Automatic conversion between String and Data.Text in haskellHaskell中String和Data.Text之间的自动转换
【发布时间】:2014-05-03 17:23:48
【问题描述】:

正如 Nikita Volkov 在他的问题 Data.Text vs String 中提到的那样,我也想知道为什么我必须在 haskell 中处理不同的 String 实现 type String = [Char]Data.Text。在我的代码中,我经常使用packunpack 函数。

我的问题:有没有办法在两种字符串类型之间进行自动转换,这样我就可以避免经常写packunpack

在 Python 或 JavaScript 等其他编程语言中,如果需要,可以在整数和浮点数之间进行自动转换。我也可以在haskell中达到类似的效果吗?我知道,上面提到的语言是弱类型的,但我听说 C++ 也有类似的特性。

注意:我已经知道语言扩展 {-# LANGUAGE OverloadedStrings #-}。但据我了解,这种语言扩展只适用于定义为"..." 的字符串。我想对从其他函数获得的字符串或函数定义中作为参数的字符串进行自动转换。

扩展问题: Haskell. Text or Bytestring 也涵盖了 Data.TextData.ByteString 之间的区别。有没有办法在StringData.TextData.ByteString这三个字符串之间进行自动转换?

【问题讨论】:

  • 如果你想要类型推断,没有这样的东西,也不可能。
  • AFAIK 对此的回答是否定的,Haskell 不会自动在类型之间转换。您只能对文字进行自动转换,因为字符串文字的类型为 AsString a => a,就像数字文字的类型为 Num a => a,但您不会获得运行时值的自动转换。
  • 感谢您的快速回答!

标签: string haskell type-conversion


【解决方案1】:

没有。

Haskell 没有出于技术、哲学和几乎宗教原因的隐含强制。

作为评论,在这些表示之间进行转换并不是免费的,而且大多数人不喜欢你隐藏着潜在的昂贵计算的想法。此外,将字符串作为惰性列表,将它们强制为 Text 值可能不会终止。

我们可以通过将字符串文字"foo" 脱糖为fromString "foo"fromStringText 自动将文字转换为Texts,只需调用pack

问题可能是问你为什么要强迫这么多?是否有一些为什么您需要如此频繁地 unpack Text 值?如果您不断将它们更改为字符串,则会有点违背目的。

【讨论】:

  • 感谢您的回答和解释。我只是问,因为我想知道我是否可以省略经常使用的packùnpack(我需要 Data.Text,因为它更节省内存,但我使用许多使用字符串的包)
  • 如果你不得不unpack 将数据传递给其他包,你或多或少失去了Text 的大部分优势。
  • 顺便说一句,我很想知道“几乎是宗教”的原因是什么。
【解决方案2】:

几乎是的:Data.String.Conversions

Haskell 库使用不同的类型,因此在许多情况下别无选择,只能大量使用转换,这很令人讨厌 - 重写库并不是真正的选择。

我看到了两个具体问题,其中任何一个都可能是 Haskell 采用的一个重大问题:

  • 编码最终需要您要使用的库的特定实现知识。这对于高级语言来说是一个大问题

  • 简单任务的性能很差 - 这是 通才语言的big issue

从特定类型中抽象出来

根据我的经验,第一个问题是花费时间猜测包含正确函数的包名称,以便在基本上对相同数据进行操作的库之间进行管道连接。

对于那个问题,有一个非常方便的解决方案:Data.String.Conversions package,前提是您对 UTF-8 作为默认编码感到满意。

这个包提供了多个不同类型之间的单一cs 转换函数。

  • String
  • Data.ByteString.ByteString
  • Data.ByteString.Lazy.ByteString
  • Data.Text.Text
  • Data.Text.Lazy.Text

所以你只需import Data.String.Conversions,并使用cs,它将根据输入和输出类型推断出正确版本的转换函数。

例子:

import Data.Aeson              (decode)
import Data.Text               (Text)
import Data.ByteString.Lazy    (ByteString)
import Data.String.Conversions (cs)

decodeTextStoredJson' :: T.Text -> MyStructure
decodeTextStoredJson' x = decode (cs x) :: Maybe MyStructure

注意:在 GHCi 中,您通常没有给出目标类型的上下文,因此您可以通过明确说明结果的类型来指导转换,例如 read

let z = cs x :: ByteString

性能和对“真正”解决方案的呼声

目前我还不知道任何真正的解决方案 - 但我们已经可以猜到方向

  • 要求转换是合法的,因为数据不会改变;
  • 最佳性能是通过出于管理目的将数据从一种类型转换为另一种类型来实现的;
  • 强制是邪恶的——甚至是强制的。

因此方向必须是使这些类型没有区别,即在它们都派生的原型下(或之上)协调它们,允许使用不同的派生组合函数,而无需转换。

注意:我绝对无法评估这个想法的可行性/潜在缺点。可能会有一些非常好的塞子。

【讨论】:

  • 你能说明一个cs的ghci应用吗? Prelude Data.String.Conversions Data.String.Conversions> cs "stuff" :10:1: error: • 约束中的非类型变量参数:ConvertibleStrings [Char] b(使用 FlexibleContexts 来允许这样做) • 当检查推断的类型 it :: forall b。 ConvertibleStrings [Char] b => b
猜你喜欢
  • 2012-12-27
  • 1970-01-01
  • 1970-01-01
  • 2010-11-29
  • 1970-01-01
  • 2019-05-01
  • 1970-01-01
  • 2013-05-24
  • 2021-02-21
相关资源
最近更新 更多