gpt4 book ai didi

haskell - 是否有可能在haskell中有一套理解?

转载 作者:行者123 更新时间:2023-12-04 00:41:08 28 4
gpt4 key购买 nike

在 Haskell 中,我们有列表生成器,例如:

[x+y | x<-[1,2,3], y<-[1,2,3]]

我们得到
[2,3,4,3,4,5,4,5,6]

如果元素已经在列表中,是否可以有一个不会自动添加元素的集合生成器?

在我们的示例中,我们将获得:
[2,3,4,5,6]

如果是这样,怎么做?如果尚未实现,您将如何实现?

最佳答案

Haskell 可以做到这一点,但不是开箱即用的。

基本的基础是列表推导式也可以写成一个单子(monad)绑定(bind)链,在列表单子(monad)中:

Prelude> [x+y | x<-[1,2,3], y<-[1,2,3]]
[2,3,4,3,4,5,4,5,6]
Prelude> [1,2,3] >>= \x -> [1,2,3] >>= \y -> return (x+y)
[2,3,4,3,4,5,4,5,6]

...或者,具有更好的可读性 do -syntax(单子(monad)绑定(bind)的语法糖)
Prelude> do x<-[1,2,3]; y<-[1,2,3]; return (x+y)
[2,3,4,3,4,5,4,5,6]

事实上,有一个语言扩展也可以将所有列表理解转换为这种单子(monad)链的语法糖。元组(又名作家)单子(monad)中的示例:
Prelude> :set -XMonadComprehensions 
Prelude> [x+y | x <- ("Hello", 4), y <- ("World", 5)] :: (String, Int)
("HelloWorld",9)

所以真的,我们需要的只是一个集合单子(monad)。这很明智,但是 Data.Set.Set不是 上的单子(monad)哈斯克 (所有 Haskell 类型的类别)但只有满足 Ord 的子类别约束(这是查找/避免重复所必需的)。然而,在集合的情况下,有一个 hack 允许从实际的 monad 实例中隐藏该约束;它用于 set-monad package .等等:
Prelude Data.Set.Monad> [x+y | x<-fromList[1,2,3], y<-fromList[1,2,3]]
fromList [2,3,4,5,6]
instance Monad Set 所需的 hack是有代价的。它是这样工作的:
{-# LANGUAGE GADTs, RankNTypes #-}
import qualified Data.Set as DS

data Set r where
Prim :: (Ord r => DS.Set r) -> Set r
Return :: a -> Set a
Bind :: Set a -> (a -> Set b) -> Set b
...

这意味着: Data.Set.Monad.Set Int 类型的值并不真正包含一组具体的整数。相反,它包含一个用于计算的抽象语法表达式,该计算产生一个集合作为结果。这对性能不利,特别是它意味着不会共享值。所以不要将它用于大型套装。

有一个更好的选择:直接将它用作适当类别中的 monad(仅包含可排序的类型)。不幸的是,这需要更多的语言弯曲,但这是可能的;我做了一个例子 in the constrained-categories library .

关于haskell - 是否有可能在haskell中有一套理解?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48850285/

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