通过添加元素修改当前列表 - Haskell 101

mf2*_*295 4 haskell list immutability

我想在一个Director名为的数据类型变量的"movies"列表中添加一个元素billy.

type Name  = String
type Movie = String
data Director = Director {name:: Name, movies::[Movie]}
    deriving (Show)
let billy = Director "Billy J." ["Good movie 1"]

--addMovieToDirector :: Movie -> Director -> Director
addMovieToDirector m (Director n ms) = Director n (m:ms)
Run Code Online (Sandbox Code Playgroud)

问题是之前的功能没有更新比利的电影列表,它创建了一个Director带有所需列表的新内容(更改不存储在比利上).如何在不创建另一个的情况下操作比利的列表Director?我明白,Haskell使用常量,但是每次修改列表时我应该创建一个不同的'billy'"变量"吗?

谢谢!

net*_*tom 7

您想要做的事情可以描述为"就地修改"或"使用可变数据".

Haskell有很多方法可以做到这一点.由于任何事物的就地修改几乎总是被认为是"副作用",所以这些事情只能在IO monad中完成,或者用肮脏的技巧来完成unsafePerformIO.

这些是一些高级主题,在初学者层面上,将Haskell值视为完全不可变是有益的.

所以是的,你无法修改变量.实际上根本没有"变量".

将其billy视为值的名称,而不是变量.

Haskell中的所有函数都可以使用参数,并计算一些没有任何副作用的结果.

对于来自命令式语言的人来说,这可能是最大的心理障碍:"如果我无法修改数据,我该如何使用数据?"

答案是:你应该像巨型装配线那样构建你的程序:原材料(原始数据,初始参数等)在开头就放在线上(你调用的第一个函数),每个工作站(函数)做一些事情有用(返回一个值),消耗前一个工作站的结果.最后,有价值的东西可能会脱离生产线.

我所描述的是简单的函数组合:如果你需要在一个值之后,c之后b,之后执行任务,那么你可以将其写为,或者更确切地说.ax(c . b . a) xc (b (a x))c $ b $ a x

这样,您可以编写程序而无需显式更改任何内容,只描述如何使用旧内容创建新内容.

这听起来非常低效,事实上,函数式编程有一些性能影响(更不用说懒惰)了.然而,编译器足够聪明,能够弄清楚用Haskell编写的程序,并以某种方式对其进行优化.

我希望很快就会有意义.:)

哦,欢迎来到Haskell.;)

  • 顺便说一句,Haskell中的术语"变量"用于数学.变量"x""变化"因为如果我们定义`fx = 2*x + 4`我们以后可以在几个不同的`x`s上调用`f`,使得参数"变化".这与命令式编程中的变异不同,但在同一个`f`的调用中,我们可以改变`x`的值. (3认同)