Reputation: 250
I'm fairly new to Haskell, and to get better I'm trying to make a simple web server. I wanted to make how I represent pages extendable, so my idea was to make webpages be a list of Renderable data (like how you can make a list of objects that implement a certain interface in Java) where Renderable is
class Renderable a where
render :: a -> IO String
Unfortunately I learned that lists MUST be a concrete type, so I can only make a list of one type of Renderable data. Also it seems impossible to create data that is constrained by a typeclass, so I can't make something like RenderList data. My temporary solution has been like this:
myPage =
[render $ someData
,render $ someMoreData
,render $ someOtherData
...
]
but this feels awkward, makes the use of a typeclass have no benefit, and feels like there should be a better way. So I'm wondering what ways could I restructure what I have to be cleaner, more in line with standard Haskell practices, and still be easily extendable?
Thanks.
Upvotes: 15
Views: 4954
Reputation: 8266
You're trying to implement an object-oriented style of design. In Java, for example, you'd have a List<Renderable>
and you'd be all set. This design style is a little bit less natural in Haskell; you need to create a wrapper type for a bounded existential as demonstrated on the Haskell wiki page for existential types. For example:
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
You can then have a list of Renderable
, which you can render however you like. Like I said, though, that is sort of an OO style which is less natural in Haskell. You can probably avoid this by rethinking your data structures. You say that you "wanted to make how you represent pages extendable"; consider other ways of doing that instead.
Unrelated: I'm guessing render
doesn't need to produce an IO String
action. Try to keep IO
out of the core of your design, if you can.
Upvotes: 13
Reputation: 2779
Check out this page on haskell heterogenous collections. It provides ideas of several approaches.
Upvotes: 5