[Haskell-beginners] Equivalence of Inheritance

Michael Katelman katelman at uiuc.edu
Tue Dec 14 23:20:19 CET 2010


I often find myself in a similar predicament, become frustrated, and
after I've wasted a lot time ultimately decide that I'm making perfect
the enemy of good.

One possible option that hasn't been mentioned is to try and enforce
safety at the module boundary, perhaps by making MensGroup a newtype
and instead of exporting the constructor to export some other function
that ensures only men wind up in a MensGroup. Sounds cumbersome to me,
though.

-Mike

On Tue, Dec 14, 2010 at 3:53 PM, Russ Abbott <russ.abbott at gmail.com> wrote:
> Ozgur pointed out this notition p at Man{}.  What I would like is something
> like this.
> type Man = Person at Man{}
> type MensGroup = [Man]
>
> -- Russ
>
>
> On Tue, Dec 14, 2010 at 1:45 PM, Michael Katelman <katelman at uiuc.edu> wrote:
>>
>> Without going too exotic, I see two choices. Keeping the single type
>> Person makes what you are asking for, as far as I know, impossible
>> (dependent types). For human readability you could consider
>>
>> type MensGroup = [Person]
>> type WomensGroup = [Person]
>>
>> If you split Person into two types, Man and Woman, there are
>> repercussions for the aggregate group type
>>
>> type Group = [Either Man Woman]
>>
>> -Mike
>>
>>
>> On Tue, Dec 14, 2010 at 3:30 PM, Russ Abbott <russ.abbott at gmail.com>
>> wrote:
>> > Now that this is straightened out, I went back to what I was doing in
>> > the
>> > first place and realized that I haven't solved my problem.
>> > Given
>> >
>> > data Person =
>> >       Man {name :: String, age :: Int, prostateCondition :: Condition}
>> >   | Woman {name :: String, age :: Int, ovaryCondition    :: Condition}
>> >
>> > I'd like to define something like this.
>> >
>> > type MensGroup = [Man]
>> >
>> > Is there a way to do something like that?
>> > -- Russ
>> >
>> >
>> > On Tue, Dec 14, 2010 at 1:06 PM, Russ Abbott <russ.abbott at gmail.com>
>> > wrote:
>> >>
>> >> That's good. (It's more or less the way I was doing it.)  What I wanted
>> >> to
>> >> avoid was this.
>> >>
>> >> getGenderSpecificCondition (  Man _ _ cond) = cond
>> >> getGenderSpecificCondition (Woman _ _ cond) = cond
>> >>
>> >> I know it seems like a small thing, but I would like to be able to
>> >> write
>> >> it like this.
>> >>
>> >> getGenderSpecificCondition p
>> >>    | p == (Man _ _ cond) = cond
>> >>    | p == (Woman _ _ cond) = cond
>> >>
>> >> But that's not legal syntax.  A pattern can't appear in that context.
>> >> But
>> >> this does the job.
>> >>
>> >> getGenderSpecificCondition :: Person -> Condition
>> >> getGenderSpecificCondition p
>> >>    | isMan p = prostateCondition p
>> >>    | isWoman p = ovaryCondition p
>> >>
>> >> isMan (     Man _ _ cond) = True
>> >> isMan _ = False
>> >> isWoman (Woman _ _ cond) = True
>> >> isWoman _ = False
>> >>
>> >> That works! prostateCondition and ovaryCondition are both defined on
>> >> Person. (I'm surprised to see that.)
>> >>
>> >> *Person> Group [Man "Harry" 32 OK, Woman "Sally" 29 Good]
>> >> Harry(32, OK)
>> >> Sally(29, Good)
>> >>
>> >> Also
>> >>
>> >> *Person> prostateCondition (Woman "Sally" 29 Good)
>> >> *** Exception: No match in record selector prostateCondition
>> >> *Person> prostateCondition (Man "Harry" 29 Good)
>> >> Good
>> >>
>> >> -- Russ
>> >>
>> >>
>> >> On Tue, Dec 14, 2010 at 12:31 PM, Michael Katelman <katelman at uiuc.edu>
>> >> wrote:
>> >>>
>> >>> Perhaps this?
>> >>>
>> >>> https://gist.github.com/741048
>> >>>
>> >>> -Mike
>> >>>
>> >>> On Tue, Dec 14, 2010 at 2:27 PM, Russ Abbott <russ.abbott at gmail.com>
>> >>> wrote:
>> >>> > What I'm after is a version of my example that compiles.  Can you
>> >>> > make
>> >>> > one?
>> >>> >
>> >>> > -- Russ
>> >>> >
>> >>> >
>> >>> > On Tue, Dec 14, 2010 at 12:18 PM, Antoine Latter
>> >>> > <aslatter at gmail.com>
>> >>> > wrote:
>> >>> >>
>> >>> >> Sorry, I really don't know enough about what you're after to
>> >>> >> attempt
>> >>> >> that.
>> >>> >>
>> >>> >> But you'll need to change you're signatures of the form:
>> >>> >>
>> >>> >> > function :: Person -> Foo
>> >>> >>
>> >>> >> to something of the form:
>> >>> >>
>> >>> >> > function :: Person p => p -> Foo
>> >>> >>
>> >>> >> Because again, a type class can not be used as a type.
>> >>> >>
>> >>> >> Antoine
>> >>> >>
>> >>> >> On Tue, Dec 14, 2010 at 2:12 PM, Russ Abbott
>> >>> >> <russ.abbott at gmail.com>
>> >>> >> wrote:
>> >>> >> > What got fouled up is all the adjustments I had to make to the
>> >>> >> > other
>> >>> >> > declarations.
>> >>> >> > Can you complete the example so that it compiles using
>> >>> >> >
>> >>> >> > class Person p where ...
>> >>> >> >
>> >>> >> > I'd very much like to see an example that actually compiles.
>> >>> >> >
>> >>> >> > Thanks.
>> >>> >> > -- Russ
>> >>> >> >
>> >>> >> > On Tue, Dec 14, 2010 at 11:58 AM, Antoine Latter
>> >>> >> > <aslatter at gmail.com>
>> >>> >> > wrote:
>> >>> >> >>
>> >>> >> >> On Tue, Dec 14, 2010 at 1:52 PM, Russ Abbott
>> >>> >> >> <russ.abbott at gmail.com>
>> >>> >> >> wrote:
>> >>> >> >> > If gender is a field in a Person type, then a Person must have
>> >>> >> >> > both
>> >>> >> >> > an
>> >>> >> >> > ovaryCondition and a prostateCondition.  That seems awkward.
>> >>> >> >> > Regarding
>> >>> >> >> >      class Person p where
>> >>> >> >> > I started down that path but got completely fouled up.
>> >>> >> >>
>> >>> >> >> How did this get fouled up? Every class declaration must take
>> >>> >> >> arguments - here, 'p' is the argument for the class.
>> >>> >> >>
>> >>> >> >> Thanks,
>> >>> >> >> Antoine
>> >>> >> >
>> >>> >> >
>> >>> >
>> >>> >
>> >>> > _______________________________________________
>> >>> > Beginners mailing list
>> >>> > Beginners at haskell.org
>> >>> > http://www.haskell.org/mailman/listinfo/beginners
>> >>> >
>> >>> >
>> >>
>> >
>> >
>
>



More information about the Beginners mailing list