哈斯克尔努力理解类型声明和缩写
在我关注的有关 Haskell 的课程中,我正在学习类型声明。目前,它正在讨论缩写,我对此感到困惑,而且我无法在网上找到我正在寻找的信息。
它给出了以下示例:
type Pair a = (a, a)
连同一段文字: Abbreviations - new name for existing types
我在文档中看到了一个与上面代码非常相似的示例:
type Name = String
但从中我仍然无法理解上面的例子。
我正在努力理解它试图解释的内容,所以其他人可以为我理解它并给出它在程序中使用的简单示例吗?
回答
这是一个类型别名[Haskell wiki]。它通常用于为更复杂的类型命名。
例如,如果您定义一个函数:
sum2 :: Pair Int -> Int
sum2 (x, y) = x + y
然后在幕后,因此决定:
sum2 :: (Int, Int) -> Int
sum2 (x, y) = x + y
类型别名通常用于
- 给一个特殊的结构一个更方便的名字;
- 缩短复杂的类型;和
- 以便于从类型切换。
例如 aString
定义为:
type String = [Char]
String
因此,A只是一个Char
演员列表。但是签名与String
关注它与文本数据一起工作的事实。
类型别名通常用于抽象出类型的复杂性。例如,我们可以定义一个类型Operator
:
type Operator a = a -> a -> a
因此,这是将两个 type 参数映射到 typea
值的函数的别名a
。如果我们以后想要创建使用此运算符的函数,这很有趣。例如:
maxOperator :: Ord a => Operator a -> Operator a -> Operator a
maxOperator f g x y = max (f x y) (g x y)
这更有可能比以下内容更具可读性:
maxOperator :: Ord a => (a -> a -> a) -> (a -> a -> a) -> (a -> a -> a)
maxOperator f g x y = max (f x y) (g x y)
如果我们以后使用Operator (Operator a)
,它肯定更具可读性,因此解析为(a -> a -> a) -> (a -> a -> a) -> a -> a -> a
。
如果您还不完全清楚您将使用什么类型,有时会使用最终类型。例如,如果你正在实现一个包并且你还没有决定使用Float
s 或Double
s,你可以定义一个类型别名:
type Scalar = Float
如果您后来改变主意,可以将其重写为type Scalar = Double
,并且您使用过的所有地方Scalar
现在都将解析为Double
。
- Fantastic. I see now, it is *essentially* to make everything more readable, understandable, and all things related. It, of course, adds functionality with your last example, but it's purpose is to abstract away from the unnecessary *behind-the-scenes* stuff. Thanks, Willem, it totally makes sense now 🙂