理解Haskell

时间:2015-11-05 01:21:43

标签: haskell types

我有以下类型:

type Name = String

type Assignation a = Name -> a

和以下函数声明:

actAsig :: Assignation a -> Name -> a -> Assignation a

此函数应返回一个新的Assignation,它返回所提供的Name新分配的值,以及之前为其他Name分配的值。

2 个答案:

答案 0 :(得分:7)

如果我理解的话,actAsig的规范是给定的

assignation1 :: Assignation a
newName :: Name
newValue :: a

assignation2 = actAsig assignation1 newName newValue

assignation2的要求是

assignation2 name = if name == newName then newValue else assignation1 name

所以,你可以这样写出来:

actAsig :: Assignation a -> Name -> a -> Assignation a
actAsig assignation1 newName newValue name = 
    if name == newName then newValue else assignation1 name

答案 1 :(得分:3)

Cactus已经出色地解决了您对actAsig函数实现的任何问题,但是,我觉得帖子标题中的问题没有得到解决。

首先,Haskell既有值级语言(Object Language)又有类型级语言(Metalanguage)。它们都很强大,但通常不是同样强大,至少不是同样的事情。但是,有些事情在两面都有效,例如常量,变量和函数。

类型级别常量为:

type Name = String

- 这通常称为“类型别名”:它表示Name(几乎)所有方面都等同于String。此引入新类型,仅为现有类型引入新名称。如果您不想使用datanewtype引入实际的新类型,这对于使代码中的意图更具可读性很有用,在这种情况下,您将引入一组新值需要从现有的值集(即类型)映射。因此,type只是方便,如果您愿意,而不是安全措施,而不是datanewtype

但是,Haskell类型级语言也支持函数,即从1种或更多种类型到某种现有类型的映射。您可以将其视为参数化别名,可以这么说。

type Assignation a = Name -> a

这将创建一个名为Assignation的类型函数,其参数为a。给定类型a,它返回一些类型,在本例中为类型Name -> a。因此Assignation Int会返回Name -> Int; Assignation Person会返回Name -> Person,依此类推。请注意,有时类型函数不会使用它们的一个或多个参数,就像值级函数一样:

type Empty a = ()

如果我们结合这些新知识,我们就可以开始考虑类型级别评估/缩减,即仅在类型签名,类型函数,类型类约束计算等边界内进行的评估。

让我们一步一步地将它应用于actAsig的类型签名:

Assignation a -> Name   -> a -> Assignation a
Assignation a -> String -> a -> Assignation a
(Name -> a)   -> String -> a -> (Name -> a)
(String -> a) -> String -> a -> (String -> a)

因此,您在上一行中看到的高阶函数类型是actAsig的实际类型,所有抽象都被消除/减少。

在人类语言术语中,签名描述了一个

的功能
  1. 使用函数f将字符串映射到某种类型a的值。
  2. 采用字符串
  3. 获取该类型的值a
  4. 返回与f相同类型的新功能。
  5. 所以在某种程度上,actAsig处理函数:它接受函数并返回新的,可能已修改的函数。

    此外,Haskell还具有(有点基本)模糊类型级别和值级别之间的界限的方法,通过使类型领域中的计算涉及到值级别的引用(依赖性),但这超出了本文的范围,并将引领我们进入Dependent TypesDependent Type Theory的世界。