25

私が話しているのは、次のことを定義することはできないということです。

data A = A {name :: String}
data B = B {name :: String}

GHCはこれを単純な関数に脱糖するだけであり、これを解決する慣用的な方法は次のようになります。

data A = A {aName :: String}
data B = B {bName :: String}

class Name a where
  name :: a -> String

instance Name A where
  name = aName

instance Name B where
  name = bName

これを書いた後、私はそれがあまり好きではありません...このタイプクラスは脱糖プロセスの一部ではありませんでしたか?


Aeson JSON解析を書いているときに、その考えが浮かびました。すべてのデータ型のインスタンスを導出するのFromJSONが簡単すぎる場合は、すべてを手作業で書き出す必要がありました(現在は1,000行を超えてカウントしています)。nameデータレコードのような、または単にデータレコードに名前を付けるvalueことは、それほど珍しいことではありません。

http://www.haskell.org/haskellwiki/Performance/Overloadingは、関数のオーバーロードが実行時のオーバーヘッドをもたらすと述べています。しかし、実際には、コンパイラがコンパイル時にこれを解決できず、内部で異なる名前を付けることができない理由がわかりません。

2012年のこのSOの質問は、多かれ少なかれ歴史的な理由を述べており、2006年のメールスレッドを指しています。最近何か変わったことはありますか?

実行時のオーバーヘッドがいくらかあるとしても、ほとんどの人は気にしないでしょう。ほとんどのコードはパフォーマンスが重要ではないからです。

これを実際に可能にする隠された言語拡張機能はありますか?繰り返しますが、よくわかりません...しかし、イドリスは実際にこれを行っていると思いますか?

4

3 に答える 3

4

多くの、ほとんどの場合マイナーな理由。1つは、より良い答えによって提起された問題です。最初の引数だけでオーバーロードするだけでは、すべての有用なケースを処理するには不十分です。

あなたは「脱糖」することができます

data A { name :: String }
data B { name :: Text   }

の中へ

class Has'name a b | a -> b where
    name :: a -> b

data A { aName :: String }
instance Has'name A String where
    name :: aName

data B { bName :: Text   }
instance Has'name B Text   where
    name :: bName

しかし、それはまだ標準になっていないGHC拡張(機能従属性)を必要とするでしょう。これらの場合、「name」は「単なる」関数ではないため、レコードの作成、更新、およびパターンマッチングに「name」だけを使用することはできません(ビューパターンが役立つ場合があります)。おそらく、テンプレートHaskellで非常によく似たものをやってのけることができます。

于 2013-01-31T15:12:20.453 に答える
3

レコード構文の使用

data A { name :: String }

関数を暗黙的に定義します

name :: A -> String

との両方Aを定義するとB、次の{ name :: String }型定義が競合しnameます。

name :: A -> String
name :: B -> String

2つの型を定義すると、提案された暗黙の型クラスがどのように機能するかは明確ではありません。

data A { name :: String }
data B { name :: Text }

次に、問題を競合する型クラス定義に移しました。

class Has'name a where
     name :: a -> String

class Has'name a where
     name :: a -> Text

原則として、これは何らかの方法で解決できますが、これはレコードのいくつかのトリッキーな競合する望ましいプロパティの1つにすぎません。Haskellが定義されたとき、より野心的で複雑なものを設計しようとするよりも、限定的なサポートではなく単純なものを使用する方がよいと判断されました。レコードに対するいくつかの改善がさまざまな時期に議論されており、このHaskell Cafeスレッドなど、長年の議論があります。おそらく、HaskellPrimeのために何かがうまくいくでしょう。

于 2013-01-25T23:27:50.633 に答える
0

私が見つけた最善の方法は、プリプロセッサを使用して、このかなりばかげた問題を解決することです。

Haskellパーサー全体が通常のライブラリとして利用できるため、HaskellとGHCはこれを簡単にします。すべてのファイルを解析し、その名前変更スキームを実行することができます(たとえば、«data A {name::String}»および«leta= A "Betty" innamea»を«dataA{a_Name::String}»および«に名前関数が適用されるデータのタイプに応じて、タイプリゾルバを使用してa = A "Betty" in aName a»)とし、コンパイルのためにそれらを書き出します。

しかし正直なところ、それはGHCに統合されるべきです。その通りです。これが含まれていないのはばかげています。

于 2013-05-03T15:09:02.653 に答える