如何在Haskell中建模类层次结构? [英] How to model class hierarchies in Haskell?

查看:112
本文介绍了如何在Haskell中建模类层次结构?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我是C#开发人员。从OO方面来说,我从接口,类和类型层次的角度开始思考。由于Haskell缺乏OO,有时候我发现自己陷入了困境,我无法想出一种用Haskell建模的方法。

如何在Haskell中模拟真实世界中涉及类层次结构的情况,如下所示: http://www.braindelay.com/danielbray/endangered-object-oriented-programming/isHierarchy-4.gif <我们假设以下操作:人类可以说话,狗可以吠叫,并且一个物种的所有成员都可以与之交配如果他们具有相反的性别,则属于同一物种。我会在haskell中这样定义它:

  data Gender = Male |女性获得公式b 
$ b class物种s其中
gender :: s - >性别

- 如果s1和s2可以构想后代
matable则返回true :: Species a => a - > a - > Bool
matable s1 s2 =性别s1 / =性别s2

data Human = Man |女人
数据犬=狗|贱卖

实例种类Human其中
性别男人=男性
性别女人=女性

实例种类犬类其中
性别狗=男性
性别Bitch =女性

树皮Dog =woof
树皮Bitch =哇

说话人s =男人说++ s
说女人s =女人说++ s

现在操作 matable 的类型为 Species s => s - > s - > Bool bark 的类型为 Canine - >字符串 speak 的类型为 Human - >字符串 - >字符串



我不知道这是否有帮助,但考虑到问题的抽象性,这是我可以提出的最好的



编辑:回复Daniel的评论:

集合的简单层次结构可能如下所示(忽略已存在的类如Foldable和Functor):

  class Foldable f其中
fold ::(a - > b - > a) - > a - > f b - > a

class可折叠m => Collection m其中
cmap ::(a - > b) - > m a - > m b
cfilter ::(a - > Bool) - > m a - > m a

类可转换我在哪里
atIndex :: i a - > Int - >
$ b实例Foldable []其中
fold = foldl

实例集合[]其中
cmap = map
cfilter = filter

instance Indexable []其中
atIndex =(!!)

sumOfEvenElements ::(Integral a,Collection c)=> c a - > a
sumOfEvenElements c = fold(+)0(cfilter even c)

现在sumOfEvenElements需要任何种类的积分集合,并返回该集合中所有偶数元素的总和。


I am a C# developer. Coming from OO side of the world, I start with thinking in terms of interfaces, classes and type hierarchies. Because of lack of OO in Haskell, sometimes I find myself stuck and I cannot think of a way to model certain problems with Haskell.

How to model, in Haskell, real world situations involving class hierarchies such as the one shown here: http://www.braindelay.com/danielbray/endangered-object-oriented-programming/isHierarchy-4.gif

解决方案

Let's assume the following operations: Humans can speak, Dogs can bark, and all members of a species can mate with members of the same species if they have opposite gender. I would define this in haskell like this:

data Gender = Male | Female deriving Eq

class Species s where
    gender :: s -> Gender

-- Returns true if s1 and s2 can conceive offspring
matable :: Species a => a -> a -> Bool
matable s1 s2 = gender s1 /= gender s2

data Human = Man | Woman
data Canine = Dog | Bitch

instance Species Human where
    gender Man = Male
    gender Woman = Female

instance Species Canine where
    gender Dog = Male
    gender Bitch = Female

bark Dog = "woof"
bark Bitch = "wow"

speak Man s = "The man says " ++ s
speak Woman s = "The woman says " ++ s

Now the operation matable has type Species s => s -> s -> Bool, bark has type Canine -> String and speak has type Human -> String -> String.

I don't know whether this helps, but given the rather abstract nature of the question, that's the best I could come up with.

Edit: In response to Daniel's comment:

A simple hierarchy for collections could look like this (ignoring already existing classes like Foldable and Functor):

class Foldable f where
    fold :: (a -> b -> a) -> a -> f b -> a

class Foldable m => Collection m where
    cmap :: (a -> b) -> m a -> m b
    cfilter :: (a -> Bool) -> m a -> m a

class Indexable i where
    atIndex :: i a -> Int -> a

instance Foldable [] where
    fold = foldl

instance Collection [] where
    cmap = map
    cfilter = filter

instance Indexable [] where
    atIndex = (!!)

sumOfEvenElements :: (Integral a, Collection c) => c a -> a
sumOfEvenElements c = fold (+) 0 (cfilter even c)

Now sumOfEvenElements takes any kind of collection of integrals and returns the sum of all even elements of that collection.

这篇关于如何在Haskell中建模类层次结构?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆