我从Haskell开始。我有一种情况,可以方便地使用以下类型的同义词:
type Adult = Int
type Youth = Int
但是我不能重载Adult
和Youth
上的函数,即使它们是不同类型的同义词,因此必须有两个单独的函数版本,例如。 doSomethingForAdult
和doSomethingForYouth
,接下来我尝试了
data Person = Adult Int | Youth Int
然后我可以模式匹配并使用单个版本的函数,
但后来我放弃了在函数声明中使用Adult
和Youth
作为类型的选项,这很方便。有中途吗?我看了Either
,但是从教程中的描述来看,这似乎是误用的?类似于小型类型层次结构的东西Person
位于根,Youth
和Adult
派生而且仍然是Int
的同义词,这将是完美的,但我无法弄清楚如何。
答案 0 :(得分:7)
我不明白这会被误用Either
。正如(,)
是通用product type一样,Either
完全可以接受为通用sum type,即任何形式:
data T = T1 A | T2 B C
...可以被代数地视为A + (B * C)
,相当于Either A (B, C)
。
另一方面,如果您想区分Adult
和Youth
,使用相同实际类型的同义词可能会适得其反;它们只是透明的别名。另一种方法是使用newtype
s,如下所示:
newtype Adult = Adult Int deriving (Eq, Ord, Show, Read, Num)
newtype Youth = Youth Int deriving (Eq, Ord, Show, Read, Num)
调整deriving
条款以品味;我在这里添加了Num
,因为底层类型是数字,但如果您想要的只是一个唯一标识符,那么添加或乘以它们就没有意义。此时,如果您愿意,可以使用Person
的和类型,或者定义类型类以获得正确的重载:
class Person a where
-- (etc...)
instance Person Adult where -- ...
instance Person Youth where -- ...
Person
中定义的任何函数都会在Adult
和Youth
上有效重载,让您dispatch based on type the way "overloaded" functions in other languages do。
答案 1 :(得分:4)
您想要typeclass
吗?
data Adult = Adult Int
data Youth = Youth Int
class Person a where
doSomething :: a -> b
instance Person Adult where
doSomething (Adult i) = ...
instance Person Youth where
doSomething (Youth i) = ...
这是Haskell中重载函数的典型方式。类型类Person
只有一个函数doSomething :: a -> b
。您希望成为Person
实例的每种数据类型都可以拥有自己独立的实现。如果您希望底层实现相同,那么只需使用另一个函数doSomethingGlobal :: Int -> b
,并让每个实例都等于这个新函数。
答案 2 :(得分:1)
你可以同时拥有:
type Adult = Int
type Youth = Int
data Person = Adult Adult | Youth Youth
数据构造函数与类型在一个单独的命名空间中,因此这里没有冲突。
答案 3 :(得分:0)
我建议只添加类型同义词
type Person = Int
你可以为那些兼顾两种功能的功能提供类型,例如
doSomething :: Person -> ...
(并且您可以在其他类型签名中使用Adult
和Youth
)
答案 4 :(得分:0)
我建议Person
多态:
data Person a = Person a Int
使用此定义,您可以编写Person
级别的一般函数,而不关心a
的具体值:
getInt :: Person a -> Int
getInt (Person _ i) = i
incInt :: Person a -> Person a
incInt (Person p i) = Person p (inc i)
然后,您可以定义“标签”以证实Person
:
data Adult = Adult
data Youth = Youth
现在您可以为特定类型的Person
rock :: Person Youth -> String
rock (Person Youth k) = "I rock until " ++ show k ++ " in the morning!!!"