gpt4 book ai didi

haskell - 在 Haskell 中创建泛型函数类型的集合有用吗

转载 作者:行者123 更新时间:2023-12-02 13:33:13 25 4
gpt4 key购买 nike

这是一个关于 Haskell 风格的问题。

作为教程示例,我创建了一个支持撤消重做操作的小程序。它使用具有两个堆栈的数据结构。

data History a = History [a] [a]

第一个堆栈是游戏的历史。第二个堆栈存储由undo弹出的状态。所以

undo (History (x:xs) redoStack) = History xs (x:redoStack)
undo history = history -- in case there is nothing to undo

redo (History hStack (x:redoStack)) = History (x:hStack) redoStack 
redo history = history -- in case there is nothing to redo

还有一个通用操作,可将更改应用于当前状态。

applyAChange change (History (x:xs) _) = History ((change x):x:xs) []

applyAChange的类型是

applyAChange :: (a -> a) -> History a -> History a

我决定定义一个Change类型:

type Change a = a -> a

那么applyAChange的类型就变成了

applyAChange :: Change a -> Change (History a)

这看起来很有用,我在代码的其他地方使用了 Change 类型。

<小时/>

在定义String 实例时,我发现自己定义了许多具有以下类型的函数:

convertASomethingToString :: Something -> String

所以我定义了一个 ToString 类型

type ToString a = a -> String

这使我能够用类型编写前面的函数

convertASomethingToString :: ToString <Something>

所有这些看起来都不错,并且使代码信息更丰富。我的问题是

  1. 这样的事情有多少值得做?
  2. 只要有人这样做,创建一个由这些类型定义组成的模块并导入它是否有意义?这是标准做法吗?
  3. 是否已经存在具有有用类型的广泛使用的此类模块?

谢谢。

最佳答案

正如前面提到的,您可以使用 Data.Monoid 中的 Endo 新类型来代替 Change 类型别名。有时处理包装/展开可能会很不方便。但如果您想要可组合的更改,您可以在其 Monoid 实例中找到一些有用的东西。

关于您的 History 数据类型:它是 Haskell 世界中众所周知的 ListZipper 。您可以在不同的地方阅读有关此概念的内容。但在您的代码中,您已经可以使用 hackage 上的现有包:http://hackage.haskell.org/package/ListZipper

它具有您的功能以及您可能会发现有用的其他一些功能。

ToString 类型别名基本上是一种没有 Show 约束的 show 函数类型。我不知道如何在没有 Show 类型绑定(bind)的情况下将通用内容转换为 String ,但如果不查看您的代码,我无法说更多。所以,我的观点是,您基本上不需要 ToString 类型别名。最好使用标准函数和类型类。

关于haskell - 在 Haskell 中创建泛型函数类型的集合有用吗,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40411645/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com