提问人:vik santata 提问时间:2/4/2016 最后编辑:Chris Martinvik santata 更新时间:2/4/2016 访问量:492
Haskell:Haskell中的所有名称都是不可变的?数组和列表没有区别?
Haskell: all names in Haskell are immutable? No difference between array and list?
问:
我有两个问题:
在 scala 或 F# 等 FP 语言中,有一些关键字可以识别变量是否可变。当我们说 Haskell 是一种纯粹的 FP 语言时,一切都是“不可变的”?
基于 jvm 的 Scala、基于 .net 的 F# 都区分了 “Array” 和 “List”。Haskell是以不同的方式讲述的,还是Haskell中的每个容器都是一个“列表”或“元组”?
答:
“纯洁”不是一个严格定义的概念。在Haskell中,这通常意味着函数没有副作用。但“副作用”也没有真正严格的定义。Haskell 的类型系统允许我们区分纯函数和非纯动作。并非所有内容都是不可变的,因为您可以使用 IO 操作来更改 的内容,例如。a -> b
IO a
IORef
Haskell也有数组,它们有几个不同的版本,但它们可以在你必须导入的模块中找到。
评论
IO a
main
main
IO
main :: IO a
在 Haskell 中,所有变量都是不可变的。但是,有各种特殊的数据结构支持突变。首先,您可以在 Haskell 中读取和写入文件,并且可以将文件视为一个巨大的可变变量。当然,Haskell也支持内存中的可变结构(、、、等)。因此(例如)变量始终指向同一个对象,但该对象的内容可以更改。IORef
STRef
MVar
TVar
x
IORef
变异物质被认为是一种副作用,在Haskell中,这种副作用是通过单子控制的。如果函数的类型签名未提及 ,则无法执行任何 I/O 操作。这包括改变其他线程可以看到的内存中数据。(但是,有趣的是,它不包括仅对此函数可见的变异数据。因此,你可以在纯函数内部进行突变,只要没有外部可见的影响。IO
Haskell“默认”为不可变的单链表,但也支持不可变和可变数组。修改不可变数组需要复制整个数组,将更新转换为 O(n) 操作,从而破坏数组的一个关键优势。不可变数组仍然是常量数据的出色查找表,但大多数基于数组的算法都需要可变数组,这就是为什么也提供了这些数组的原因。
上一个:优化可变数组状态繁重操作代码
下一个:FFI 中的可变数据和懒惰
评论
IORef
提供可变引用,Array.IO
提供可变数组。ST