Haskellが優れたHaskellプログラムを作成できるようにデータをどのように表現するかを理解する必要がありますか?
-
27-09-2019 - |
質問
私はJavaの背景からHaskellを学んでいます。 Javaをプログラムするとき、私はオブジェクトがどのように記憶に配置されているかとこの結果を強く理解しているように感じます。たとえば、私は正確にその方法を知っています java.lang.String
と java.util.LinkedList
したがって、私はそれらをどのように使用すべきかを知っています。 Haskellで私は少し迷子になります。たとえば、どのようにしますか (:)
仕事?気にする必要がありますか?どこかで指定されていますか?
解決
短い答えはノーです。 Haskellでプログラミングするときは、データ構造を純粋な数学的オブジェクトと考える必要があり、それらがどのようにメモリで表現されるかを心配しないでください。この理由は、副作用がない場合、本当に何もないからです に それを作成する関数と、構築されたより単純な部分を抽出するために使用できる関数を除くデータ。
のようなデータコンストラクターに関する情報を見るには (:)
, 、またはその他の用語、使用します :type
(あるいは単に :t
略して)GHCI内のコマンド:
:Prelude> :type (:)
(:) :: a -> [a] -> [a]
それはあなたにそれを伝えます (:)
コンストラクター(「短所」と発音)は、任意のタイプの値と同じタイプのリストを取得し、同じタイプのリストを返します。また、もう少し情報を入手することもできます :info
指図。これにより、データ定義がどのように見えるかが表示されます。
Prelude> :info (:)
data [] a = ... | a : [a] -- Defined in GHC.Types
infixr 5 :
これはあなたにそれを伝えます (:)
既存のリストに要素を準備するコンストラクターです。
私も強くお勧めします フーグル 名前で物事を調べるだけでなく、逆の種類の検索を行うために。あなたが探している関数の署名を知っている場所で、誰かがすでにあなたのためにそれを書いているかどうかを見つけたいと思っています。 Hoogleは、説明と例の使用法を提供するため、いいです。
誘導データの形状
私は上記で言った。メモリ内のあなたのデータの表現を知ることは重要ではないだろう...しかし、あなたは理解する必要があります 形 あなたが扱っているデータのうち、パフォーマンスの不十分な決定を避けるため。 Haskellのすべてのデータは誘導的に定義されています。つまり、再帰的に外側に展開する木のような形状があります。その定義を調べることで、データの形状を伝えることができます。これを読む方法を知ったら、そのパフォーマンスの特性については何も隠されていません:
data MyList a = Nil | Cons a (MyList a)
定義からわかるように、新しいものを取得できる唯一の方法 MyList
によってです Cons
コンストラクタ。このコンストラクターを複数回使用すると、この形状のほぼ何かになります。
(Cons a5 (Cons a4 (Cons a3 (Cons a2 (Cons a1 Nil)))))
それは枝のない単なる木です、それがリストの定義です!そして、行く唯一の方法 a1
それぞれを飛ばすことです Cons
s;したがって、最後の要素へのアクセスはです の上), 、一方、頭へのアクセスは一定の時間です。データ構造の定義に基づいてこの種の推論を行うことができたら、すべて設定されます。
他のヒント
短い答えは「いいえ」です。データレイアウトについて知る必要はありません。複雑さの知識が役立ちます。
ただし、高度に最適化されたHaskellプログラムを作成するには、ヒープ内のデータ構造の形状に関する優れた実用的な知識が不可欠です。これを支援するツールです "真空", 、Haskellデータ構造の図をレイアウトするにつれて図式化できます。
いくつかの例:
$ view "hello"
$ view (IntMap.fromList $ zip [1..10] [1..])
これがツールの使用方法の短いビデオです。 http://www.youtube.com/watch?v=x4-212umgy8