如何在Haskell中建模类层次结构? [英] How to model class hierarchies in 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屋!