除了使用Monad之外,纯函数式语言还有哪些处理状态的方法?

29 浏览
0 Comments

除了使用Monad之外,纯函数式语言还有哪些处理状态的方法?

所以我开始理解单子(在Haskell中使用)。我很好奇纯函数式语言中处理IO或状态的其他方法(无论是在理论上还是实际上)。例如,有一种被称为“mercury”的逻辑语言使用“效应类型”。在像Haskell这样的程序中,效应类型会如何工作?其他系统又是如何工作的呢?

0
0 Comments

在纯函数式编程语言中处理状态的另一种方式是使用绑定器(Monads)之外的方法。状态是什么?在Haskell中,状态可以表现为可变变量,但是你没有这个概念。你只有内存引用(IORef、MVar、Ptr等)和用于操作它们的IO/ST操作。

然而,状态本身也可以是纯的。为了理解这一点,我们来看看'Stream'类型:

data Stream a = Stream a (Stream a)

这是一串值的流。然而,对这个类型的另一种解释是一个在变化的值:

stepStream :: Stream a -> (a, Stream a)

stepStream (Stream x xs) = (x, xs)

当允许两个流进行通信时,情况变得有趣起来。这时你会得到自动机类别Auto:

newtype Auto a b = Auto (a -> (b, Auto a b))

这与Stream非常相似,只是现在每个时间点的流都会得到某些类型为a的输入值。这形成了一个类别,因此一个时间点的流可以从另一个时间点的流获得其值。

再次对这个进行不同的解释:你有两个随时间变化的计算,并允许它们进行通信。因此,每个计算都有局部状态。下面是一个与Auto同构的类型:

data LS a b =

forall s.

LS s ((a, s) -> (b, s))

0
0 Comments

纯函数式语言处理状态的另一种主要方法是独占类型,如Clean语言中所示。简而言之,对状态(包括真实世界)的处理只能使用一次,并且访问可变状态的函数返回一个新的处理。这意味着第一次调用的输出是第二次调用的输入,强制顺序评估。

Disciple编译器在Haskell中使用效果类型,但据我所知,为了在GHC中启用它,需要进行相当多的编译器工作。关于细节的讨论我留给那些比我更了解的人。

Disciple编译器不编译Haskell代码,它编译的是Disciple代码,这是一种不同但相关的语言。这不能集成到GHC中,因为效果类型不是Haskell的一部分。

它自己的文档声称它是Haskell的一个方言,我愿意承认这一点。它似乎与GHC及其众多扩展几乎没有什么不同,尽管与不使用扩展的代码集成起来更困难。

0
0 Comments

这篇文章主要讨论了在纯函数式语言中处理状态的方式。作者首先解释了`IO`和`State`是不同的概念,`State`可以通过在每个函数中传递额外的参数并返回额外的结果来实现,而`IO`则需要在其实现中使用一些魔法。然后作者讨论了如果在没有`IO`的情况下重新设计`IO`,可能会采用的一些方式,比如通过定义一个`InteractIO`类型来实现交互式输入输出。接着作者介绍了早期版本的Haskell中处理`IO`的方式,包括使用`DialogueIO`和`ContIO`类型来表示输入输出。最后作者解释了为什么需要`Monad`,即通过抽象出`Monad`类型类,可以统一处理不同的类型,使得编写代码更加方便。

从上述内容中可以看出,作者提到了纯函数式语言处理状态的方式主要有以下几种:

- 通过在每个函数中传递额外的参数并返回额外的结果来实现状态。

- 定义一个新的类型来表示输入输出,通过函数的方式来实现输入输出的交互。

- 使用特定的类型来表示输入输出,并通过特定的机制来处理输入输出。

通过抽象出`Monad`类型类,可以统一处理不同类型的操作,使得编写代码更加方便。所以,回答问题"除了使用Monad,纯函数式语言还有哪些处理状态的方式?"的原因是为了介绍纯函数式语言中处理状态的方式,并解释为什么需要`Monad`。解决方法是通过介绍纯函数式语言中处理状态的几种方式,并说明`Monad`的作用和好处。

0