web-dev-qa-db-ja.com

haskellのStringとData.Text間の自動変換

Nikita Volkovが彼の質問で述べたように Data.Text vs String また、haskellで異なるString実装type String = [Char]Data.Textを処理しなければならない理由も疑問に思いました。私のコードでは、pack関数とunpack関数を頻繁に使用しています。

私の質問:packunpack頻繁に?

PythonやJavaScriptのような他のプログラミング言語では、たとえば、必要に応じて整数と浮動小数点数の間の自動変換があります。haskellでもこのようなものに到達できますか?言及された言語は知っています弱い型ですが、C++にも同様の機能があると聞きました。

注:私はすでに言語拡張{-# LANGUAGE OverloadedStrings #-}を知っています。しかし、私が理解しているように、この言語拡張は"..."として定義された文字列にのみ適用されます。他の関数から取得した文字列、または関数定義の引数として持っている文字列の自動変換が必要です。

拡張質問:Haskell。テキストまたはバイト文字列Data.TextData.ByteStringの違いもカバーしています。 3つの文字列StringData.Text、およびData.ByteStringの間で自動変換を行う方法はありますか?

29
Stephan Kulla

番号。

Haskellには、技術的、哲学的、そしてほとんど宗教的な理由から、暗黙の強制はありません。

コメントとして、これらの表現間の変換そうではありません無料であり、ほとんどの人は、あなたが隠していて潜在的に高価な計算が潜んでいるという考えを嫌います。さらに、文字列をレイジーリストとして使用すると、文字列をText値に強制変換しても終了しない場合があります。

文字列リテラル"foo"fromString "foo"およびText for OverloadedStringにデシュガーすることにより、リテラルをfromStringsで自動的にTextsに変換できます。 packを呼び出します。

問題は、なぜそんなに強要しているのかを尋ねることかもしれません。なぜそんなに頻繁にunpackText値を必要とするのですか?それらを常に文字列に変更すると、目的が少し損なわれます。

29
jozefg

ほぼはい:Data.String.Conversions

Haskellライブラリはさまざまなタイプを使用するため、変換を多用せざるを得ない状況が多くありますが、それ自体が不快です。ライブラリの書き換えは実際の選択とは見なされません。

私は2つの具体的な問題を見ており、どちらもHaskellの採用にとって潜在的に重大な問題です。

  • コーディングには、使用するライブラリの特定の実装知識が必要になります。これは、高級言語にとって大きな問題です。

  • 単純なタスクのパフォーマンスが悪い-これはgeneralist言語の 大きな問題 です。

特定のタイプからの抽象化

私の経験では、最初の問題は、基本的に同じデータを操作するライブラリ間で配管するための適切な関数を保持するパッケージ名を推測するのに費やされる時間です。

その問題には、本当に便利な解決策があります:Data.String.Conversionspackage 、デフォルトのエンコーディングとして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

パフォーマンスと「真の」ソリューションへの叫び

私はまだ本当の解決策を知りません-しかし私たちはすでに方向を推測することができます

  • データは変更されないため、変換を要求することは正当です。
  • 最高のパフォーマンスは、管理目的でデータをあるタイプから別のタイプにnot変換することによって達成されます。
  • 強制は悪です-強制的ですら。

したがって、方向は、これらのタイプを異ならないようにすること、つまり、それらがすべて派生するアーチタイプの下(または上)でそれらを調整し、変換する必要なしに、異なる派生を使用して関数を合成できるようにすることでなければなりません。

注意:このアイデアの実現可能性/潜在的な欠点を評価することは絶対にできません。非常に健全なストッパーがあるかもしれません。

29
Titou