13

私は Haskell にかなり慣れていないので、うまくなるために単純な Web サーバーを作ろうとしています。ページの表現方法を拡張可能にしたかったので、Web ページを Renderable データのリスト (Java で特定のインターフェースを実装するオブジェクトのリストを作成する方法など) にすることを考えました。Renderable は

class Renderable a where
    render :: a -> IO String

残念ながら、リストは具象型でなければならないことを知ったので、Renderable データの 1 つの型のリストしか作成できません。また、型クラスに制約されたデータを作成することは不可能のようで、RenderList データのようなものを作成することはできません。私の一時的な解決策は次のとおりです。

myPage =
    [render $ someData
    ,render $ someMoreData
    ,render $ someOtherData
    ...
    ]

しかし、これはぎこちなく感じ、型クラスを使用しても何のメリットもありません。より良い方法があるはずだと感じています。では、標準的な Haskell の慣行に沿って、よりクリーンにする必要があるものを再構築し、さらに簡単に拡張できるようにするにはどうすればよいでしょうか?

ありがとう。

4

2 に答える 2

13

オブジェクト指向スタイルのデザインを実装しようとしています。たとえば Java では、 があればList<Renderable>準備は完了です。この設計スタイルは、Haskell では少し不自然です。Haskell wiki page for existential typesで示されているように、境界のある実存型のラッパー型を作成する必要があります。例えば:

class Renderable_ a where
  render :: a -> IO String

data Renderable = forall a. Renderable_ a => Renderable a
instance Renderable_ Renderable where
  render (Renderable a) = render a

Renderableその後、好きなようにレンダリングできるのリストを取得できます。しかし、私が言ったように、それは Haskell ではあまり自然ではないオブジェクト指向スタイルのようなものです。データ構造を再考することで、おそらくこれを回避できます。「ページの表現方法を拡張可能にしたかった」とあなたは言います。代わりにそれを行う他の方法を検討してください。

無関係:アクションrenderを生成する必要はないと思います。可能であれば、デザインの核心にIO String近づかないようにしてください。IO

于 2012-10-08T02:57:44.077 に答える
4

haskell の異種コレクションに関するこのページを確認してください。いくつかのアプローチのアイデアを提供します。

于 2012-10-08T01:11:56.457 に答える