gpt4 book ai didi

haskell - Type构造函数接受相同类型的几种数据类型,如何获得同名访问器?

转载 作者:行者123 更新时间:2023-12-04 14:54:46 26 4
gpt4 key购买 nike

简短:我有一个解决我的问题的方法,但它似乎有点矫枉过正,所以我想知道我是否遗漏了什么。

长 :
我有 2 个数据类型,一个动物类型和一个所有者类型。两者都具有相同的“属性”年龄和名称。为了简单起见,我希望能够在 Animal 和 Owner 上无差别地调用年龄和名称

type Age = Int
type Name = String

data AnimalType = Dog | Cat | Snake
deriving (Read, Show,Eq)

--with datatype and pattern matching
data Animal = Animal AnimalType Name Age
deriving(Show, Eq)
name (Animal _ name _) = name
age (Animal _ _ age) = age
animalType (Animal animalType _ _) = animalType

data Owner = Owner Name Age [Animal]
deriving(Show,Eq)
name (Owner name _ _) = name
age (Owner _ age _) = age
animals (Owner _ _ animals) = animals

garfield = Animal Cat "Garfield" 8
rantanplan = Animal Dog "Rantanplan " 4
kaa = Animal Snake "Kaa" 15

dupond = Owner "Dupont" 28 [garfield, rantanplan]
bob = Owner "Bob" 35 [kaa]

这不编译,
  Multiple declarations of `age'

同样的事情也不适用于 Record 语法。

这样做,一个人被迫为所有者和动物的年龄命名不同的年龄。

然后我挖了一下,发现我可以使用 typeclass 来实现这一点。
type Age = Int
type Name = String

class Nameable a where
name:: a -> Name

class Ageable a where
age:: a -> Age


data AnimalType = Dog | Cat | Snake
deriving (Read, Show,Eq)

--with datatype and pattern matching
data Animal = Animal AnimalType Name Age
deriving(Show, Eq)

instance Nameable Animal where
name (Animal _ name _) = name

instance Ageable Animal where
age (Animal _ _ age) = age

animalType (Animal animalType _ _) = animalType


data Owner = Owner Name Age [Animal]
deriving(Show,Eq)

instance Nameable Owner where
name (Owner name _ _) = name

instance Ageable Owner where
age (Owner _ age _) = age

animals (Owner _ _ animals) = animals



garfield = Animal Cat "Garfield" 8
rantanplan = Animal Dog "Rantanplan " 4
kaa = Animal Snake "Kaa" 15

dupond = Owner "Dupont" 28 [garfield, rantanplan]
bob = Owner "Bob" 35 [kaa]

这种方法几乎与 Java 中接口(interface)的使用相同。第一个不起作用的方法更接近于旧的 C 结构方法。

有没有更快的方法来达到同样的效果?

最佳答案

Haskell 中的记录(及其访问器)是……次优的。也就是说,这个关于重复记录字段的特殊问题有一个解决方法(从 GHC 8.0 开始),形式为 DuplicateRecordFields 。扩大。请注意,必须以明确的方式使用记录访问器(这里没有发生花哨的多态性)。

{-# LANGUAGE DuplicateRecordFields #-}

type Age = Int
type Name = String

data AnimalType = Dog | Cat | Snake
deriving (Read, Show, Eq)

data Animal = Animal
{ animalType :: AnimalType
, name :: Name
, age :: Age
} deriving(Show, Eq)

data Owner = Owner
{ name :: Name
, age :: Age
, animals :: [Animal]
} deriving(Show, Eq)

garfield = Animal Cat "Garfield" 8
rantanplan = Animal Dog "Rantanplan " 4
kaa = Animal Snake "Kaa" 15

dupond = Owner "Dupont" 28 [garfield, rantanplan]
bob = Owner "Bob" 35 [kaa]

关于haskell - Type构造函数接受相同类型的几种数据类型,如何获得同名访问器?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47160950/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com